For my research I need to be able to query a Microsoft analysis server(2012) Data cube with the Unity game engine. For the connection there is a Microsoft Authentication needed and Unity is using the Mono Develop libraries for SQL connections which gives me a problem. Since so far i haven't found a solution for Mono to be able to use a Microsoft Authentication.
I want to find a nice way to use windows authentication inside a domain at the customer. Since the end application must be able to connect to Data cubes preferably using a connection string.
Data cubes using an IIS server that allows for HTTP connection using SOAP will not always be available depending on the costumer set-up.
Also the desire to build the application on multiple platforms makes it hard to add custom library's if there even is a custom library for this request since I haven't been able to find one yet.
My current less fortunate side options are:
Build an extra windows application with visual studio that query's the data and parses it to Unity (But requires and extra application to
run).
Use the http SOAP connection with an IIS service (But requires the analysis server to be set-up with IIS which isn't always possible depending on the customer).
Find a library that allows me to use Microsoft Authentication (but probably only works on the windows platform, or doesn't work with Unity).
I'm hoping someone has already found or maybe knows a good solution that works for Unity without giving the limitations I've mentioned above.
I am using the Microsoft.AnalysisServices.AdomdClient; with visual studio that works fine for visual studio build but doesn't work in monodevelop in unity.
try
{
using (AdomdConnection adcon = new AdomdConnection(connectionString))
{
adcon.Open();
using (AdomdCommand adcmd = adcon.CreateCommand())
{
adcmd.CommandText = textBox3.Text.ToString();
AdomdDataReader dr = adcmd.ExecuteReader(CommandBehavior.CloseConnection);
while (dr.Read())
{
for (int i = 0; i < dr.FieldCount; i++)
textBox2.AppendText(dr[i] + (i == dr.FieldCount - 1 ? "" : ", ") + Environment.NewLine);
}
dr.Close();
textBox2.AppendText(adcmd.CommandText.ToString() + Environment.NewLine + Environment.NewLine);
adcmd.Connection.Close();
}
adcon.Close();
}
}
catch(Exception e)
{
textBox2.AppendText(e.ToString() + Environment.NewLine);
}
Thank you for any suggestions, feedback or answers!
Something you could try would be using the relational SQL Server engine as a kind of proxy. The relational SQL Server engine should be available whereever Analysis Services is available.
You could set up a linked server in the relational SQL Server which links to the Analysis Services server using the Analysis Services OLEDB client. How to set up linked servers is described here.
Then you can send MDX to this linked server, and get back the results in the relational engine like this:
select * from openquery(AdventureWorksOLAP,
'select [Measures].[Sales Amount] on columns from [Adventure Works]')
where AdventureWorksOLAP is the name of your linked server.
However, you should be aware that the column names are strange (containing closing square brackets, which need to be escaped within the square brackets enclosing column names by doubling). E. g. the above query would have a column that you have to access as [[Measures]].[Sales Amount]]]. Furthermore, all cell values come back as nvarchar and might need to be casted to a numeric type in order to work with them.
Maybe you could encapsulate the column name changing and column typecasting into a stored procedure.
And you could use SQL server authentication to access the relational database.
Related
I'm working with Dynamics365 CE in the cloud. I'm trying to run some rather involved queries that I've built up as SQL scripts (using the wonderful "SQL-4-CDS" plugin for the XrmToolBox).
Now I know I can connect to the Dataverse data store through the TDS endpoint (if enabled - it is in my case), and from SSMS, it works just fine:
Server Name = myorg.crm4.dynamics.com,5558
Authentication = Azure Active Directory - Password
User Name = my company e-mail
I can connect to Dataverse, and run my queries - all is great.
Now I'd like to do the same from C# code (running on .NET 6) that I'm writing, that should end up being an Azure Function in the end - so it's a "server-to-server", behind-the-scenes, no interactive login context kind of scenario.
I can connect to Dataverse via the TDS endpoint using this connection string - as long as I'm running the app interactively - as me, in my user context:
Server=myorg.crm4.dynamics.com,5558;Authentication=Active Directory Password;Database=my_dbname;User Id=my_email;Password=my_pwd;
However - this won't work with a server-to-server "daemon"-style setup.
Since I'm using .NET 6 (for the Azure Function), and since I want to run some custom SQL statements, I cannot use the "CRM XRM Client" tooling (with the IOrganizationService classes) - I need to use straight ADO.NET - any idea would I could define an ADO.NET compatible connection string, that would use a Client ID and Client Secret (which I both have at my disposal)?
I've tried a great many values for the Authentication=...... setting - but none have worked so far. Any place I can find a complete list of the supported values for this connection string parameter?
Thanks for any help or pointers!
I'm writing a WPF application.
Trying to use the normal method of getting a connection returns an error similar to: "The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine."
ACE.OLEDB has never been installed on this machine so this error makes sense.
I'm trying to create this application in a way so that our users won't need to contact IT to have the application installed. Getting IT involved is a no go situation and the project will be abandoned.
Another team has an Access database (accdb) that I want my application to extract information (only read, no insert or update). I talked to the team and they won't convert this database back to an earlier version (mdb).
After my research I assume that installing ACE.OLEDB without using Admin privileges is impossible. Because of this and my application requirement of not requiring admin privileges I need to start looking for "Mutant"/Dirty solutions that don't involve ACE.OLEDB.
I tried using power-shell but I'm getting the same problems as I had with C# (requires IT to install ACE.OLEDB).
I have two potential solutions. One write a VBA script that opens up the database and dumps a query result into a file. My C# application would call this VB script and then parse the created file.
The second option is to create a new Access process using Process.Start(fullFilePath) and somehow pass the command to execute a query and somehow pass the results back to the executing application (either via a method return or first to a file).
How would you get the data out?
Is there a way for C# to duplicate the DB file and convert it from (accdb -> mdb)?
This is the second question I ask that is very similar.
C# Connecting to Access DB with no install
The difference between the two (to prevent this is a duplicate question) is that in the previous question I was looking for ways to install ACE.OLEDB without admin privileges while here I'm just looking for any other work around.
Found a workaround. It uses Microsoft.Office.Interop.Access found in NuGet.
var accApp = new Microsoft.Office.Interop.Access.Application();
accApp.OpenCurrentDatabase(#tests.DatabasePath);
Microsoft.Office.Interop.Access.Dao.Database cdb = accApp.CurrentDb();
Microsoft.Office.Interop.Access.Dao.Recordset rst =
cdb.OpenRecordset(
"SELECT * FROM Users",
Microsoft.Office.Interop.Access.Dao.RecordsetTypeEnum.dbOpenSnapshot);
while (!rst.EOF)
{
Console.WriteLine(rst.Fields["username"].Value);
rst.MoveNext();
}
rst.Close();
accApp.CloseCurrentDatabase();
accApp.Quit();
I have recently been changing some C# programs to add proper parameterizing to some MySQL statements that had originally been written with concatenated strings. Invariably, I've run into some problems with my statements and I can't find a way to directly see the complete MySQL statement with parameters applied other than this workaround that I have where I pass the MySQL command to this:
private string getMySqlStatement(MySqlCommand cmd)
{
string result = cmd.CommandText.ToString();
foreach (MySqlParameter p in cmd.Parameters)
{
string addQuote = (p.Value is string) ? "'" : "";
result = result.Replace(p.ParameterName.ToString(), addQuote + p.Value.ToString() + addQuote);
}
return result;
}
This works, but I was wondering if there was a more proper way to see the full statement with parameters applied. Reading up on this, it looks like the parameters aren't actually applied until it reaches the server - is this correct? In that case, I suppose I can stick to my function above, but I just wanted to know if there was a better way to do it.
Note: I am just using this function for debugging purposes so I can see the MySQL statement.
MySQL supports two protocols for client/server communication: text and binary. In the text protocol, there is no support for command parameters in the protocol itself; they are simulated by the client library. With Connector/NET, the text protocol is always used, unless you set IgnorePrepare=true in the connection string and call MySqlCommand.Prepare() for each command. So it's most likely the case that you are using the text protocol. This is good, because it will be easier to log the actual statements with parameters applied.
There are three ways to view the statements being executed:
Use Connector/NET Logging
Add Logging=true to your connection string and create a TraceListener that listens for the QueryOpened event. This should contain the full SQL statement with parameters interpolated. Instructions on setting this up are here.
Use MySQL Server Logging
Enable the general query log on your server to see all queries that are being executed. This is done with the --general_log=1 --general_log_file=/var/path/to/file server options.
Packet Sniffing
If you're not using SslMode=Required (to encrypt the connection between client and server), then you can use WireShark to capture network traffic between your client and the server. WireShark has MySQL Protocol analysers that will inspect MySQL traffic and identify command packets (that contain SQL queries). This option is ideal if you aren't able to modify your client program nor change server logging settings.
Kindly bear with me. I am a Microsoft SQL Server person with loads of Visual Studio experience, but I need to get something done using a MySQL database.
I am trying to create a little tool here that will allow our developers to quickly update database records, and I am using Visual Studio to create a small Windows Form to do this.
In a Microsoft SQL Server connection string, I could write something like this:
Server=myServerAddress;Database=myDataBase;User Id=username;Password=password;
In a MySQL connection string, there appear to be multiple other options, but the first one looks basically the same:
Server=myServerAddress;Database=myDataBase;Uid=username;Pwd=password;
When I attempt to open the MySQL connection from my PC, I get the exception listed in the title (actually, it shows the Uid value and the IP Address of my PC instead of localhost, but I am hoping more people will recognize the error easier this way):
public static void MySQLi_Connect() {
m_err = null;
var str = Properties.Settings.Default.ConnStr;
try {
m_conn = new MySqlConnection(Properties.Settings.Default.ConnStr);
m_conn.Open();
} catch (MySqlException err) {
ErrorLog("MySQLi_Connect", err);
}
}
I did a search, and it seems that the Uid on MySQL needs to be granted access from the specific IP Address that the connection is being made from.
Further, I found this on the mysql.com doc pages:
If you do not know the IP address or host name of the machine from which you are connecting, you should put a row with '%' as the Host column value in the user table. After trying to connect from the client machine, use a SELECT USER() query to see how you really did connect. Then change the '%' in the user table row to the actual host name that shows up in the log. Otherwise, your system is left insecure because it permits connections from any host for the given user name.
A few things:
It looks like I can connect to MySQL by using a % setting in the Uid jp2code, but MySQL says I need to change that back right away to remove system vulnerability.
Microsoft SQL Server did not seem to require this - or, if it did, I simply never was slapped in the face with this vulnerability issue like MySQL is doing.
Now, I ask:
If this is going to be a tool used by different developers on different PCs, is it common practice to turn the blind eye to this horrendous system vulnerability?
Is this not really as big of a concern as MySQL is making it appear?
What is the best way to continue with a Windows Forms application that needs to connect from various locations? Obviously, I do not want to continuously be adding more entries for a particular application every time another developer wants to use the tool or someone tries to run it from a different PC.
You can configure the security of your MySQL server as strong as you like, usually you dont connect users but applications. So if you have your root user without password in production environment is your fault. Usually developers have access to development environment, so this is not a big deal.
Of course try to have as many users as roles you need, for your example I think one user is enough. In production use a secure config file for save a secure password and set you mysqlserver restricted.
I was having the same issue and I found out that the password wasn't correct.
GO to your sql command line and type the code below:
mydb in the line below is the name of the database you are working on.
passwd in the line has to match the password you have in c# code so in your case "password"
grant all privileges on mydb.* to myuser#localhost identified by 'passwd';
Like OP says you can wildcard the hostname portion. I used this on our dev-server (not recommended for production servers):
update mysql.user set host = '%' where host='localhost';
Then I had to restart the server to make MySQL use it (propably I could just have restarted the MySQL service).
I have one database with one mirror in high-safety mode (using a witness server at the moment but planing to take him out), this database will be used to store data gathered by a c# program.
I want to know how can I check in my program the state of all the SQL instances and to cause/force a manual failover.
is there any c# API to help me with this?
info: im using sql server 2008
edit: I know I can query sys.database_mirroring but for this I need the principal database up and runing, I would like to contact each sql instance and check their status.
Use SQL Server Management Objects (SMO).
SQL Server Management Objects (SMO) is a collection of objects that are designed for programming all aspects of managing Microsoft SQL Server. SQL Server Replication Management Objects (RMO) is a collection of objects that encapsulates SQL Server replication management.
I have used SMO in managed applications before - works a treat.
To find out the state of an instance, use the Server object - is has a State and a Status properties.
after playing around a bit I found this solution (i'm not if this is a proper solution, so leave comments plz)
using Microsoft.SqlServer.Management.Smo.Wmi;
ManagedComputer mc = new ManagedComputer("localhost");
foreach (Service svc in mc.Services) {
if (svc.Name == "MSSQL$SQLEXPRESS"){
textSTW.Text = svc.ServiceState.ToString();
}
if (svc.Name == "MSSQL$TESTSERVER"){
textST1.Text = svc.ServiceState.ToString();
}
if (svc.Name == "MSSQL$TESTSERVER3") {
textST2.Text = svc.ServiceState.ToString();
}
}
this way i'm just looking for the state of the services (Running/Stoped) and is much faster, am I missing something?