SQL Server connection count issue - c#

I am using SQL Server 2008 Enterprise + .Net 3.5 + C# + ADO.Net. I am using the following SQL statement to monitor connection number, is it correct? If yes, my confusion is, one connection from ADO.Net client maps to only one connection in the following statement? Or one ADO.Net connection could maps to multiple connections here?
SELECT * FROM sys.dm_os_performance_counters WHERE object_name = 'SQLServer:General Statistics'
(Monitor User Connections row)
thanks in advance,
George

Use SELECT * FROM sys.dm_exec_connections to find all the connections. The client_net_address has the client address so you can track down the origin of connections.
Use SELECT * FROM sys.dm_exec_sessions to find all the sessions (sessions in general map 1 to 1 with connections unless MARS is used). The program_name column will contain the value of the application name you passed in in the connection string and allows you to identify your own connections.
Use SELECT * FROM sys.dm_exec_requests to see all the current executing batches (requests).
The performance counter would only give you one value, the number of current connections:
SELECT cntr_value
FROM sys.dm_os_performance_counters
WHERE object_name = 'SQLServer:General Statistics'
and counter_name = 'User Connections'

Would this work for your needs? I'm confused if you're trying to count the number of connections. Your question seems to say no, where your comment implies yes to me.
Sp_who2 'Active'

By default, the underlying SQL Server driver code uses a connection pool. You'll find that the number of physical connections "owned" by your application will grow over time to the current limit, but this is different from the number that are "in use".
This avoids renegotiating security, etc. on each link, speeding up your application's database access.
As mentioned by #sgmarshall, use the sp_who2 stored procedure to determine what each of the connections are currently doing.

Related

Connection forcibly closed while executing the subqueries in the QuickBooks online ODBC driver connection

I am using the trial version of QuickBooks Online ODBC (QODBC) driver and configured the DSN named QuickBooks Online Data as well as QuickBooks Online Data QRemote
I have ensured the connection using the test tool and I am able to execute the SQL queries properly using the mentioned test tool and C# code.
Please find some of the example queries that works fine:
select * from Account
select account.TimeCreated,account.TimeModified, TaxRate.ListID from account
left outer join TaxRate on account.ListID = TaxRate.ListID
select AVG(RateValue),SUM(RateValue) from TaxRate
select Top 5 ListID,RateValue from TaxRate
While trying to execute the subqueries in the test tool, I am facing the following issue.
Subquery used:
select ListID from (select ListID, TimeCreated from Account)
Exception: ERROR [42S00] ExecDirect Packet Header - Received Error:10054,
An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host used a "hard close"
ERROR [42S00] Error Invalid Socket. Either socket is closed, or the socket reference is invalid.
For more information please visit: qodbc.com/links/invalidsocket
I have tried the suggested solution in the error message, still, the issue is not resolved.
Also, tried the subquery execution in the c# console application as well and faced the same issue.
Anyone, please let me know the possible solution to resolve this issue?
Hopefully this helps:
select tmp.ListID from (select ListID, TimeCreated from account) as tmp
(Not sure about the QODBC syntax, so I went for plain SQL)
Edit:
Could be also that the QODBC system does not support full SQL syntax, so nested selects will just fail (with a very strange error message indeed - but programmers are notoriously bad at writing helpful error messages). You can test this quickly with the simplest nested select possible:
select * from (select 1)
or:
select * from (select 1) as tmp
If both fail, it means the SQL interpreter on the other end of your request is subpar. The workaround would be to just "rephrase" your select statements in a way that avoids this unsupported syntax. I could help with that if I'd know what is the actual request.
I'm not 100% sure on this, but this may be that the ODBC backend being used here (QuickBooks Online) only supports a very limited sub-set of the SQL standard.
You can see the query syntax supported here:
https://developer.intuit.com/app/developer/qbo/docs/learn/explore-the-quickbooks-online-api/data-queries
What seems relevant is to note that QuickBooks Online does not support subqueries AT ALL.
I wonder if QODBC basically just passes the raw SQL through to QuickBooks... and QuickBooks doesn't support it, so it crashes/errors?

connect to database c#

I'm trying to connect to a DB on a server using C# but with no luck.
I tried using this:
public static string m_ConnectionString =
#"Network Library=dbmssocn; Data Source=*server ip*,*port*; database=*db name*; " +
#"User id=*db username*; Password=*db pass*;";
public static SqlConnection myConnection = new SqlConnection(m_ConnectionString);
I get this error:
Connection Timeout Expired. The timeout period elapsed while
attempting to consume the pre-login handshake acknowledgement. This
could be because the pre-login handshake failed or the server was
unable to respond back in time. The duration spent while attempting
to connect to this server was - [Pre-Login] initialization=9343;
handshake=5654;
when I used myConnection.Open();
I tried also to set the timeout to int.MaxValue and it didn't work.
A very good source for SQL Server (and many other) connection strings is http://www.connectionstrings.com/sql-server/. Depending whether you are connecting through ODBC, OLE DB or Native Client, you have to choose another connection string.
Try
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;
or
Server=myServerAddress;Database=myDataBase;Trusted_Connection=True;
There are a lot of options to choose from, depending on the exact SQL Server version, the security type and many more.
UPDATE
First you have to choose a data access technology.
.NET Framework Data Provider for SQL Server (SqlConnection), Is the preferred way of accessing the SQL Server from .NET code. (See When to use the SQL Native Client for a comparison)
Native Client: Is a very fast way of accessing the SQL Server and supports the new features, as it accesses the SQL Server TDS protocol directly and works for non .NET code. It should be preferred for non .NET code.
ODBC: Is relatively fast and compatible to a lot of different databases. Choose this one if the data base type might change in future or if you are accessing "exotic" databases.
OLEDB: For SQL Server it is relatively slow and will be depreciated by Microsoft.
Then you have to choose between SQL Server Authentication (User/Password) and Windows Authentication. I would choose the latter if possible. With Windows Authentication the SQL-Server assumes that if you logged in successfully to Windows you are a trusted user. The Windows user name will then be mapped 1 to 1 to a SQL-Server user. Of course this user then must still have been granted the rights requested for the operations that he will perform on the SQL Server (like SELECT, INSERT, UPDATE, DELETE). If the DBA didn't install Windows Authentication, you will have to go with uid/pwd.
This worked for me:
string connectionString =
"Data Source=192.168.123.45;Initial Catalog=MyDatabase;Integrated Security=SSPI;";
using (SqlConnection connection = new SqlConnection(connectionString)) {
using (SqlCommand command = new SqlCommand(
"SELECT Region FROM dbo.tlkpRegion WHERE RegionID=30", connection)) {
connection.Open();
string result = (string)command.ExecuteScalar();
MessageBox.Show("Region = " + result);
}
}
I think that Data Source=*server ip*,*port*; should be Data Source=*server ip*:*port*;, replacing , with :. But if the port is not specific, I don't think you really need it. Also you're not defining a driver, I don't know it this works without it.
Also a advice: look up LINQ to SQL or ADO.NET Entity Data Model. Those can really simplify use of databases and using LINQ you can write a query inside code which is a lot similar to sql and Visual Studio also helps with intellisense so you don't have to remember all table and column names.

Stateless WCF service and database connection pooling

The question has been asked before here in StackOverflow, but in my experience, the answers were actually wrong. At least for .NET Framework 4.0 and SQL Server 2005 they are wrong.
I would need help to sort this out once and for all.
The question is - can a stateless WCF service use database connection pooling in some way?
See Can a Stateless WCF service ...
The earlier answers essentially stated that there is no problem and no difference to any other ADO.NET scenarios. However, I have not been able to get a stateless WCF service to use the connection pooling EVER, while I can see it always work outside WCF services. No matter what connection strings or parameters I am trying to use, it does not do it.
Database connection pooling is meant to be enabled by default, so a simple connection string should get me there, for instance on SQL Server Express:
SqlConnection sqlCn = new SqlConnection("Data Source=SERVER\SQLEXPRESS; Initial Catalog = xDB; Integrated Security = SSPI;")
Using this connection, in a Windows Form application, if I do 3 consecutive rounds of sqlCn.Open() -- query the database -- sqlCn.Close(), I am getting a long delay (for instance 2 seconds) on the first sqlCn.Open(), and no delays at all on queries and open / close afterwards. Exactly what I expect with database connection pooling.
But if I make 3 calls to a WCF service containing the same sqlCn.Open() -- query the database -- sqlCn.Close() code, I am getting the 2 second initial slow startup for EVERY single call.
My guess is that the connection pooling is entirely controlled by the ADO.NET objects created by my code, and since I am instantiating any ADO.NET classes I use (such as SqlConnection etc) inside my WCF service, they get destroyed when my service call is over and the connection pool along with it.
This may not be true, but if not, is there anything wrong with what I have done?
Anyone have any experience with that?
(Please do test any assumption or theory before posting)
1) Here's the documentation:
http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx
When a connection is first opened, a connection pool is created based
on an exact matching algorithm that associates the pool with the
connection string in the connection. Each connection pool is
associated with a distinct connection string. When a new connection is
opened, if the connection string is not an exact match to an existing
pool, a new pool is created. Connections are pooled per process, per
application domain, per connection string and when integrated security
is used, per Windows identity. Connection strings must also be an
exact match; keywords supplied in a different order for the same
connection will be pooled separately.
2) Per the same link, "By default, connection pooling is enabled in ADO.NET."
3) This is completely independent of whether the WCF call in question is stateless or not.
4) Finally:
We strongly recommend that you always close the connection when you
are finished using it so that the connection will be returned to the
pool. You can do this using either the Close or Dispose methods of the
Connection object, or by opening all connections inside a using
statement in C#, or a Using statement in Visual Basic. Connections
that are not explicitly closed might not be added or returned to the
pool.
I managed to resolve it myself.
I had to explicitly state "Pooling = true" (and add a non-zero "Min Pool Size") to my connection string. Then it was working consistently. If this was not set, it would sometimes factually work as expected, but mostly not.
I tested it also with different user accounts (SQL Server authentication with user name / password versus "Integrated Security = SSPI"). Both approaches work for a WCF service as long as you set "Pooling = true".
No data if this is a problem only for my installation / SQL Server version / ADO.NET version but it sure did take quite a while to resolve.

How to Efficently Test Whether an SQL Server Instance is Running in C#

I have an SQL Server (2008 R2) based (C# WinForms) application that predominantly runs on a local machine using a local installation of SQL Server 2008 R2. One problem I have is that if the user does not have a server instance running and tries to execute some commands or perform some operations, the queries are sent off to SQL Server and it takes an age to throw an SqlException telling me the requested instance is not started.
I have read the following question and associated answers, but these solutions are far from ideal. WMI seem very much over-kill and I do not want to have to include extra .dlls in my installation package for the software if it can be avoided.
I have also come accross the SqlDataSourceEnumerator Class documented here
// Retrieve the enumerator instance and then the data.
SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
which dumps the available connection into a DataTable. However, there seems to be inherent problems with returning all the available connections:
"All of the available servers may or may not be listed. The list can vary depending on
factors such as timeouts and network traffic. This can cause the list to be different
on two consecutive calls." - MSDN.
There has to be a set way of dealing with this problem. Say I have the following SqlConnection string:
Data Source=localhost;Initial Catalog=MyDB;Integrated Security=True;Connection Timeout = 0
what can I use as an efficient (this is crucial) check as to whether the selected instance ('localhost' [the default instance] or 'SomeInstanceName') is running?
Thanks for your time.
I don't think you need to worry about timeouts or network issues when the server and client are the same machine. Just attempting to connect is about efficient as you're going to get, the crucial part is going to be how long do you let the connection attempt try before you give up (connection timeout). You can shorten that window obviously, but if you make it too short, then the problem doesn't really make sense.
You can change the connection timeout to be a shorter period, but essentially, the only way it knows that a server isn't there, is from a timeout.
Any technique you use will likely have the exact same timeout issue.
If you know the instance name, such as "MSSQL$InstanceName" you can use the System.ServiceProcess.ServiceController class to get a list of all services on the machine and then loop through looking to see if any ServiceName == MSSQL$InstanceName.
I have found this to be very fast plus you can check to see if it is running and start it if it is not running.
You could try opening up a simple TCP connection to the standard SQL port and see if it sticks .
set the connection timeout to some reasonably low value based on your environment.
see
http://support.microsoft.com/kb/287932
for sql serevr port numbers.

How to connect to SQL Server redundantly using C#?

I have two SQL Server machines, server1 and server2 that are redundant and have the same data.
My application wants to select data from a table in the msdb database every 1 second. But my application can connect only using one conection string. How to edit my application can work redudantly with both servers?
SQL Server 2000 SP4
Window Server 2003
C#
My connection string is
server=10.15.13.70;database=msdb;user id=sa;pwd=""
Please advise me.
Pick a server at random and insert the name or IP for that in the connection string before opening the connection.
using (SqlConnection _con = new SqlConnection("server=" + giveMeAServer() + ";database=msdb;user id=sa;pwd="))
and:
private String giveMeAServer()
{
return "10.15.13.70";
}
The proper fix, especially if you are reconnecting as often as once per second, is most likely to set up some sort of cluster on the SQL Server side, and connect to that, rather than having your application worry about load balancing the database backend.
Better is you try to open the connection for some interval say 5ms, and if connection cant be opened, switch to other server through connection string
What you are looking for is Load balancing. This is a technique that can only be applied to readonly databases. It basically spreads the load across multiple servers.
Here is a good read on load balancing with SQL Server 2000 by Microsoft.
http://technet.microsoft.com/en-us/library/cc917707.aspx
Imho, what you try to achieve should not be handled programmatically but on a hardware level.
Data Source=myServerAddress;Failover Partner=myMirrorServerAddress;Initial Catalog=myDataBase;Integrated Security=True;
(from http://www.mssqltips.com/tip.asp?tip=1289)

Categories