Why does sqlConnection.Close() not close the login? - sql-server

We have unit tests to test that our database install and uninstall features successfully work.
The unit tests use the SqlClient.SqlConnection class to check the database contents before, during and after.
Our problem is that after using SqlClient.SqlConnection, the drop login part of the uninstall fails because it claims that a user is currently logged in. Even though we have called SqlConnection.Close(), the login seems to be still open.
Our code looks a little like this:
InstallTables(); // function uses smo to create tables in a database.
string connString = CreateLogin("userName", "password"); // create login with smo
// Test the returned connection string connects to the database
using (SqlConnection con = new SqlConnection(connString))
{
con.Open();
//test code to read the DB version out of a table
//Dispose calls con.Close() - I have also tried calling it explicitly
}
DropTables(); // uses smo to drop tables from the database
DropLogin("userName", "password"); // uses smo to drop the login
The DropLogin fails with the following exception:
System.Data.SqlClient.SqlException: Could not drop login 'engageSecurity_unittest_129418264074692569' as the user is currently logged in.
If I remove all the SqlConnection code until after the DropLogin, then everything runs fine.
Does anyone know why the user is not logged out when I call SqlConnection.Close() ?
Is this something to do with connection pooling?

Unless you're explicitly disabling Connection Pooling in your connection string, my guess is that even though you're disposing the connection it is still alive in the Connection Pool (in case you decide to re-use it):
SQL Server Connection Pooling (ADO.NET)
Try disabling Connection Pooling (by adding Pooling=false; in your connection string) and see what happens.

Alternatives to Pooling=false are SqlConnection.ClearPool and SqlConnection.ClearAllPools Method.

Related

Program won't connect to SQL Server

Update: This is fixed thanks to some great help here. If you're having similar issues do the following:
Enable ALL exceptions before running
Figure out the exact error you're getting when trying to connect
Make sure that all users on SQL side have a user assigned to a login for that specific database
I've got a very nice program I've made that I'm ready to start pushing out for testing. The problem is that when I coded all of this I simply used the Integrated Security which uses my windows login to connect to the SQL Server. That worked fine as I'm a sysadmin on that whole server, including the database in question.
Now I'm ready to push this out to other users and I need to change the code to either use my login for all users (hard coded to the connection string) or use a new login specifically for that database.
I've used the following connection string and it won't work! I've also added the server to the data connections section of the server explorer but I guess I don't know how to tell the program to use that connection in my code.
I've obfuscated the password in the code below but it's written out in my code. No errors or anything when running - it just doesn't connect or pull data.
Thoughts? Thanks!
Dim strSQLConn As String = ("Server=Hertz1455;Database=AbsenceApplication;User ID=hac0421;Password=********")
Update - hertz1455 is the server name, there isn't a port that I need to use. Below is the rest of the code for when the program starts. I've also commented on some answers with the error I'm getting.
Dim strSQLConn As String = "Fleet_PTO.My.MySettings.AbsenceApplicationConnectionString"
Dim strQuery As String
Dim sqlSQLCon As SqlConnection
sqlSQLCon = New SqlConnection(strSQLConn)
Dim cmd As SqlCommand = New SqlCommand("SELECT person FROM tblSupervisor", sqlSQLCon)
sqlSQLCon.Open()
Dim myDA As SqlDataAdapter = New SqlDataAdapter(cmd)
Dim myDataTable As DataTable = New DataTable
myDA.Fill(myDataTable)
sqlSQLCon.Close()
When I change the strSqlConn to the string below, everything works just fine.
Dim strSQLConn As String = ("Data Source=Hertz1455;Initial Catalog=AbsenceApplication;Integrated Security=True")
We can only guess since the question is a bit unclear without any exceptions or warning messages.
Try this:
Create a new text file anywhere. (say Desktop)
Rename the extension to udl and open the file.
You should be seeing window.
Test your connection, see if you can connect.
Lat94 might be correct with the Server=Hertz:1455 part although it's not the default MSSQL port.
Also check your server's firewall, it might be blocking the connection request. You might be getting an exception (like connection forcefully rejected) but it might not be popping up. Check exception settings, enable everything since you find a relative clue.
Note:
Dear future viewer, please follow the comments.
Perhaps you should add the driver you're using in order to get it done, like:
Dim strSQLConn As String = ("Server=SQLOLEDB;Server=Hertz1455;Database=AbsenceApplication;User ID=hac0421;Password=********")
Is "1455 at Server=Hertz1455 the port number? Shouldn't it be Server=Hertz:1455 in that case?
Check this link for more info. It is in C#, but it will not be a problem.

Why does creating contained authentication user cause login error?

Creating a contained user in my SQL Server Express 2014 partially contained database, causes exception when performing queries on existing open connections.
Here is the SQL to turn on contained DB authentication and create the database:
EXEC sp_configure 'contained database authentication', 1
RECONFIGURE
GO
CREATE DATABASE TestContainedUserAuth CONTAINMENT = PARTIAL;
GO
USE TestContainedUserAuth;
GO
CREATE USER TestCreatorUser WITH PASSWORD='Test1234';
GO
ALTER ROLE db_owner ADD MEMBER TestCreatorUser;
GO
CREATE TABLE [dbo].[TestTable](
[TestTableID] [int] NOT NULL
) ON [PRIMARY]
GO
Here is the .Net 4.6.1 code for performing the query (please create a console project and paste this in Program.cs, and of course change server and instance name to match yours):
using System.Data.SqlClient;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
while (true)
{
using (var connection = new SqlConnection("Integrated Security=False;Data Source=localhost\\SQLEXPRESS;Initial Catalog=TestContainedUserAuth;User ID=TestCreatorUser;Password=Test1234"))
{
connection.Open();
using (var cmd = new SqlCommand(#"SELECT * FROM TestTable", connection))
{
cmd.ExecuteNonQuery();
}
}
}
}
}
}
Now, after running the C# program to perform this query in a loop, run this from SQL Management Studio (BTW, we are fully aware of the security risks associated with contained databases and with dbo users in a contained database):
IF EXISTS(SELECT * FROM sys.database_principals WHERE name = N'MyNewUser') DROP USER MyNewUser;
GO
CREATE USER MyNewUser WITH PASSWORD=N'Abcd1234';
GO
After executing CREATE USER MyNewUser (which executes successfully) in SQL Management Studio, I'm getting this exception in the C# program:
An unhandled exception of type 'System.Data.SqlClient.SqlException'
occurred in System.Data.dll
Additional information: Login failed for user
'S-1-9-3-1497860641-1239606672-4234875017-3655542527'.
A severe error occurred on the current command. The results, if any,
should be discarded.
If I modify the code to keep a reference to the connection and not open and close the connection for each query I don't get the exception. So it appears as though the exception is happening when ExecuteNonQuery attempts to re-login on the connection after the connection is obtained from the pool, but I'm not sure.
Additionally if pooling is turned off (Pooling=False in the connection string), the exception doesn't occur.
Finally, after this error occurs once on one connection, it seems like existing pooled connections are "healed" and queries executed on existing connections are successful from then on, until another 'CREATE USER' is performed.
Neither keeping a reference to a permanently open connection or turning off pooling is a practical solution to this error. Any help would be appreciated.
I think you are right. Its using an old connection from the pool.
Would an acceptable solution be to clear the application pool for that connection?
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool.aspx
Thank you for the suggestions. We decided to not use containment. The problem does not occur when using non-contained database and non-contained SQL login authentication.

How to connect to simple database table?

I don't know much about databases - Sorry if the question seems silly.
I have sql server 2012 on my machine and i create simple database table.
I want to connect to this database table thru C# code.
So, I need to know my ConnectionString.
I don't understand the parameters of the ConnectionString.
I try to google it - but still didn't find any good explanation.
Anyone can please explain the connectionString fields ?
How to define the connectionString that i will be able to connect the local database ?
thanks
Your connection string should be as simple as like below
Data Source=.;Initial Catalog=DB_NAME;Integrated Security=True"
Where
Data Source=. means local database
Initial Catalog=DB_NAME means the database it will connect to
Integrated Security=True means it will use windows authentication (no user name and password needed; it will use logged in credential)
Take a look Here
(OR)
Search in Google with key term sqlconncectionstring which will fetch you many help.
EDIT:
You are getting exception cause Initial Catalog=DB_Name\Table_001. It should be Initial Catalog=DB_Name (only database name). Provide the table name in sql query to execute. Check some online tutorial to get more idea on the same.
You use . in data source only when you are connecting to local machine database and to the default SQL Server instance. Else if you are using different server and named SQL Server instance then your connection string should look like
using(SqlConnection sqlConnection = new SqlConnection())
{
sqlConnection.ConnectionString =
#"Data Source=Actual_server_name\actual_sqlserver_instance_name;
Initial Catalog=actual_database_name_Name;
Integrated Security=True;";
sqlConnection.Open();
}
In case you are using local machine but named SQL Server instance then use
Data Source=.\actual_sqlserver_instance_name;
Initial Catalog=Actual_Database_NAME;Integrated Security=True"
using System.Data.SqlClient;
Then create a SqlConnection and specifying the connection string.
SqlConnection myConnection = new SqlConnection("user id=username;" +
"password=password;server=serverurl;" +
"Trusted_Connection=yes;" +
"database=database; " +
"connection timeout=30");
Note: line break in connection string is for formatting purposes only
SqlConnection.ConnectionString
The connection string is simply a compilation of options and values to specify how and what to connect to. Upon investigating the Visual Studio .NET help files I discovered that several fields had multiple names that worked the same, like Password and Pwd work interchangeably.
User ID
The User ID is used when you are using SQL Authentication. In my experience this is ignored when using a Trusted_Connection, or Windows Authentication. If the username is associated with a password Password or Pwd will be used.
"user id=userid;"
Password or Pwd
The password field is to be used with the User ID, it just wouldn't make sense to log in without a username, just a password. Both Password and Pwd are completely interchangeable.
"Password=validpassword;"-or-
"Pwd=validpassword;"
Data Source or Server or Address or Addr or Network Address
Upon looking in the MSDN documentation I found that there are several ways to specify the network address. The documentation mentions no differences between them and they appear to be interchangeable. The address is an valid network address, for brevity I am only using the localhost address in the examples.
"Data Source=localhost;"
-or-
"Server=localhost;"
-or-
"Address=localhost;"-or-"Addr=localhost;"
-or-"Network Address=localhost;"
Integrated Sercurity or Trusted_Connection
Integrated Security and Trusted_Connection are used to specify wheter the connnection is secure, such as Windows Authentication or SSPI. The recognized values are true, false, and sspi. According to the MSDN documentation sspi is equivalent to true. Note: I do not know how SSPI works, or affects the connection.
Connect Timeout or Connection Timeout
These specify the time, in seconds, to wait for the server to respond before generating an error. The default value is 15 (seconds).
"Connect Timeout=10;"-or-
"Connection Timeout=10;"
Initial Catalog or Database
Initial Catalog and Database are simply two ways of selecting the database associated with the connection.
"Inital Catalog=main;"
-or-
"Database=main;"

window service and sqlserver connection

i have a project in window service, when i insert the following code in Onstart() event and debug it manually then database is inserted successfully, but when i create exe file of this project and started it in task manager then does nothing...i mean it didnt save any thing to database.
try
{
SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=testing;Integrated Security=True");
SqlDataAdapter adp = new SqlDataAdapter();
cn.Open();
adp.InsertCommand = new SqlCommand("insert into testing1 values(1)", cn);
adp.InsertCommand.ExecuteNonQuery();
cn.Close();
}
catch { }
As the title of your post states "Windows service", I assume your program is running as a service. You are using integrated security, according to your connection string. Check if the account under which this runs has the rights to login to database server, and has the right to execute the insert.
You could of course also change to a fix database user account if your database is configured to allow that and there is one configured.
Edit
I also would suggest instead of an empty catch() clause, you print out/save to a log file the error message and stack trace to help diagnose the issue.

Classic ASP - SQL Server 2008 Connection String using Windows Authentication

This should be painfully simple, but I cannot come up with a working connection string for a local copy of SQL Server 2008 using Windows Authentication. I've tried using the Data Link Properties tool to create a connection string and it has no problems connecting, but when I copy paste the generated string into my ADODB.Connection object's ConnectionString property I get all sorts of fun and different errors.
Set conn = Server.CreateObject("ADODB.Connection")
conn.ConnectionString = "SQLNCLI10.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=climb4acure;Data Source=(local);"
Microsoft OLE DB Service Components (0x80040E21)
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.
I've tried a variety of similar connection strings but I cannot find one that will work with Windows Authentication. Can someone point me in the right direction?
Thanks!
Here's an easy way to generate connection strings that work.
Right-click an empty spot on the desktop and choose NEW, TEXT DOCUMENT from the context menu
Save it with a .udl extension, and click yes when it asks are you sure.
Double-click the new udl file you just created. It will open a dialogue. Go to the Provider tab, and choose the appropriate provider.
Go to the Connection tab and fill in the server name and database name, and choose NT authentication (or use a specific username and password, which is SQL authentication). Now click Test Connection. If it works, you're ready to click OK and move on to the final step. If it doesn't you need to resolve permission issues, or you've mis-typed something.
Now right-click the file on the desktop and open it in notepad. It will display the connection string that you can copy and paste to wherever you need it.
I assume you have the 2008 Native Client installed? Also, I noticed that you're missing the "provider" tag at the beginning - do you have any more luck with this one:
Provider=SQLNCLI10.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=climb4acure;Data Source=(local);
Have you had a look at connectionstrings.com? They are a pretty good reference (but, in my experience, they don't work too well in the Google Chrome browser).
Works absolutely fine:
"Provider=SQLNCLI;Server=xxxxxxxx;uid=sa;pwd=xxxxxx;database=xxxxxx;"

Resources