I have a SQL CLR stored procedure written in c# (.NET4). Its purpose is to allow a trigger on a table in a SQL Server 2012 database to call a web service which then processes the data in that table.
However, there are several different databases which will all have triggers using this assembly. My web service needs to know which database is triggered the call to it in order to know where to get the data from.
I could simply add a parameter to my stored procedure but I want to keep things simple from the database side. Is there any way, in .NET, to obtain information about the database to which the assembly is attached?
Aah, found one:
This still opens a context connection to the database, but it's about the only way I can see.
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open();
string dbName = conn.Database
}
That's from an MSDN article. Also, the MSDN article on Context Connection.
Related
It is changing my queries and appears to be fully qualifying my tables without me explicitly telling it to. Is there a way to stop it from doing that?
Here is the pertinent information as I see it. Let me know if anything else would be helpful.
We had a SQL Server named serverName. It's been in production for years. It was migrated away from a Windows 2008 Server to a Windows 2012 Server. The new server's name is sql_1234_4321 (not the real name but as terrible)
We have nth number of applications that were hitting the old serverName SQL Server so we took the old server offline and created a DNS entry for serverName that points at the new sql_1234_4321 hoping we wouldn't have to hit the connection strings for all the apps that were hitting the old server.
This worked for the most part except for some C# ASP.NET MVC apps.
They are using System.Data.SqlClient.SqlCommand.
Connection string:
Data Source=serverName;Initial Catalog=USData; Persist Security Info=True; User ID=appUn;Password=appPw
SQL query:
select FirstName from Customers
Code:
using (SqlCommand cmd = new SqlCommand(query, sqlConnection))
{
if (parameters != null)
{
cmd.Parameters.AddRange(parameters.ToArray());
}
var reader = cmd.ExecuteReader();
var results = new List<TType>();
while (reader.Read())
{
results.Add(convert(reader));
}
return results;
}
I get an error:
Could not find server 'serverName' in sys.servers.Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
Why this error? The only time serverName is referenced is in the connection string. My query should just use default namespaces once its on the server. But it appears that my query is being fully qualified at some point in the process as the following:
select FirstName from serverName.USData.dbo.Customers
I added a linked server serverName on the new sql_1234_4321 server that just points back to itself and this seemed to fix the problem. However, this feels absolutely dirty and makes me wonder if it REALLY is doing a cross server query at that point or if its smart enough to say "HEY! we are hitting ourself so don't worry about going out to the network and making this more expensive than it should be" but i doubt it.
I thought about using synonyms but the problem is we have tables with the server name in them. And there may be queries hitting the server with the server name in them so the following would not work:
CREATE SYNONYM serverName FOR sql_1234_4321;
So then it would make sense that I'd have to make a specific synonym for each database on the server:
CREATE SYNONYM serverName.database1 FOR sql_1234_4321.database1;
CREATE SYNONYM serverName.database2 FOR sql_1234_4321.database2;
CREATE SYNONYM serverName.database3 FOR sql_1234_4321.database3;
CREATE SYNONYM serverName.database4 FOR sql_1234_4321.database4;
CREATE SYNONYM serverName.database5 FOR sql_1234_4321.database5;
CREATE SYNONYM serverName.database6 FOR sql_1234_4321.database6;
CREATE SYNONYM serverName.database7 FOR sql_1234_4321.database7;
CREATE SYNONYM serverName.database8 FOR sql_1234_4321.database8;
CREATE SYNONYM serverName.database9 FOR sql_1234_4321.database9;
CREATE SYNONYM serverName.database10 FOR sql_1234_4321.database10;
As you can see, this would be a nightmare to maintain and besides that feels super dirty.
My question is this... At what point is the table name being fully qualified out based on the connection string? Is there a way to prevent that from happening?
David Browne led me to find the issue. My query actually had a view referenced and the view had the reference to the old server. Huge oversight on my part to not notice that. Thanks David
I created a new database using SQL Server 2008 R2 by using the Management Studio. The connection says (local) and I am using Windows Authentication (though I installed with mixed mode).
My questions are:
How do I connect to the DB via my C# application -
The only time I ever have done this before I just used VS Menu > Tools > Connect to DB and the drop down saw my database and connected, then right clicked on it and grabbed the connection string for use in connecting. However I'm thinking because its (local) I don't have that option.
As per Q#1 I am assuming the database file is being stored somewhere locally - I am wondering how to find that location and how I can include it with my application
Edit** Per comment: VSMenu-> View-> Server Explorer and then use add connection to connect to your local SQL Server instance and then use the database you created from the databases dropdown, and from advance settings copy the connection string created by the connection dialog
This is what I am looking for but I am missing the step during "add connection" where do I find my SQL Server I created locally? As mentioned before I have no idea where it is stored or how to find it
MSDN has an example in the SQLConnection documentation
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
}
You can then optionally use a SqlDataAdapter.
You need to use ADO.NET, which is comprised of a connection object (SqlConnection), command object (SqlCommand), parameters objects (SqlParameter) and data sets (DataSet) or data readers (SqlDataReader).
Read A Beginner's Tutorial for Understanding ADO.NET.
I've done a wcf service that deals with a database. In that WCF service i've created some stored procedures. That service is now accessible from my network (http: //myIP/MysService.csv/) and my stored procedures are accessible that way : http: //myIP/MysService.csv/MyProcedure?myParam=XXX.
I've a MVC4 application that is working with some local data (by local I mean a local database and a local WCF service, called that way for requests by example :
public int getClientID(string login)
{
var context = new MyLocalService.MyLocalEntityEntities(new Uri(http://localhost:12345/MyWCF.svc/));
var persons = context.PERSON.ToList();
var cli = from person in persons
where person.LOGIN == login
select person.CLIENT_ID;
int cliID = (int) cli.First();
return cliID;
}
Now, I'd like to plug the 2 : delete all the part that works with local data (var context=...) and replace it by a call to the stored procedure of my WCF service. How to do it ?
I've try to add my service using right click-> add as a service reference -> http: //myIP/MysService.csv/ for address by I cannot access to stored procedures. Is it the right way to work and if not, how to do it ? Thanks !
If you're going to use Stored Procedures then look at the SqlCommand class that will allow you to execute stored procedures on the database.
The other idea would be to consider what kind of Object-Relational Mapping tool you are using that may allow for SQL commands to be executed directly since you already seem to be using some LINQ in your code.
You'd pair the SqlCommand class with a SqlConnection class that have a direct connection to the database, presuming the stored procedure is MS-SQL Server or SQL Express where you want to execute the procedure in the DB. Unless you have a very different configuration than what I've seen, most calls to stored procedures are done by wrapping some using statements for the connection and command to run the procedure. Calling stored procedure from C# code has an example if you need it.
I am about to deploy my application and have came into a bit of trouble.
I have the connection string for the database held in the application.settings and need a way to check if the database exists when the program first starts up, and if it doesn't, i need the program to create it before starting the program.
I am assuming it would be a mysql statement to check if db exists, if not create. However, I don't know where or how to do this, can I create a mysql dump of a blank database with tables etc already created and use that?
I have already stored the mysql dll files locally so there is no problem with that, its just creating the database that the string wants to connect to before the application runs so there are no connection errors straight away.
Thanks.
You can do this by running the following SQL statement:
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = "my_db"
If it doesn't exist from the result set you get returned you can then create it.
This does pose questions regarding MySQL permissions and if your application should have user rights that enable such checking.
Edit in response of comments.
It isn’t clear if you create the connection string or not – I’ll assume the worst and that it is a part of the setup so your client can enter it (if you do know it the process below simplifies.
I would pass the connection string to the constructor of the MySqlConnectionStringBuilder class, this then makes it easy to connect to the database using the MySqlConnection class. I would use the properties from the new instance of the MySqlConnectionStringBuilder class (Server, Host, User etc) to setup the MySqlConnection class.
If the connection didn’t work I would return information to the user and they can update their connection string.
Once I’ve successfully connected to the database I would then use the database name from the Database property of my MySqlConnectionStringBuilder instance to build the query above.
If the command returns NULL the database doesn't exist and then needs creating, if the database does exist then the command will return the name of the database.
Now there are two paths:
It Doesn't exist – It needs creating, I would probably have an external SQL file with the create statements in (can be produced by MySQL dump by using the –nodata option). I would parse this file and execute the create statements
It does exist – I would now check the structure of the database to make sure it is compatible before continuing the installation.
I am creating a C# assembly for MS SQL Server 2005 for encryption/decryption.
I need to query the database in this assembly, and was wondering what the preferred method of connecting to the database is? I believe we would not want to have a username/password in the connection string.
Since the assembly is registered in MS SQL does it have some sort of quick way to access data in the database?
I'm a little bit of a newb as it related to Integrated Security or Trusted Connections.
You can use the following connection string when using CLR stored procedures:
using(SqlConnection connection = new SqlConnection("context connection=true"))
{
// ..
}