I'm having difficulty with an SQL query against Server 2008 from IIS7. I have a VB.NET class library which runs an update statement. The underlying code used to create the connection hasn't changed, but suddenly the query is failing in our testing and development environments. It does, however, still work against the same server/database using the slightly older code in our production environment.
I've tried setting the connection timeout in the web.config and I'm at a loss to explain the cause.
The basic structure of the query is:
Dim conn = New SqlConnection()
conn.ConnectionString = "Data Source=someserver\sqlexpress2008;Initial Catalog=DatabaseName;User ID=sa;Password=pass"
conn.Open()
Using cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "UPDATE ..."
cmd.Parameters.AddWithValue("#UName", user.name)
cmd.ExecuteNonQuery() 'fails with error
End Using
The error is:
A transport-level error has occurred when sending the request to the
server. (provider: TCP Provider, error: 0 - An existing connection was
forcibly closed by the remote host.)
I've tried restarting IIS and the SQL server and I'm totally out of ideas. I just need a fix
You need to open the connection before calling SqlCommand.ExecuteNonQuery(). You do this by calling SqlConnection.Open().
Dim conn = New SqlConnection()
conn.ConnectionString = "Data Source=someserver\sqlexpress2008;Initial Catalog=DatabaseName;User ID=sa;Password=pass"
Using cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "UPDATE ..."
cmd.Parameters.AddWithValue("#UName", user.name)
conn.Open()
cmd.ExecuteNonQuery() 'fails with error
conn.Close()
End Using
Also, ensure you database isn't in single user mode.
This helped another person who was stuck recently. You could examine the problem from the database server by setting up a SQL Server Profiler.
You can find lots of info about SQL Profiler by just googling around. Here's a site with a video that might help you get started. For starters, you would be able to see if the request is even reaching the database server.
This was a nightmare to track down. It turned out to be cause by a horrible quirk in VB.NET. Nullable datetimes seem to be coerced to DateTime.MinValue, which resulted in a DateTime.MinValue being inserted into an sql datetime. The fix was to check for either !property.HasValue && property.Value != DateTime.MinValue when setting the parameters for the command.
This is a network-level error. The database server is killing the connection for some reason. In order to troubleshoot this, I would open a connection using SSMS to the DEV and TEST servers and make sure that I can run simple queries w/o problems. It's unlikely that the issue is your library since you would be getting timeout or some other kind of errors.
as Lcarus, said, database server is killing the connection for unknown reason.
you can check the logs, to verfiy. Log path will be C:\Program Files\Microsoft SQL Server\<your instance>\MSSQL\LOG
from MSDN Blog MSDN Blog
this will occur when A connection is taken from the connection pool,
the application does not know that the physical connection is gone, an
attempt to use it is done under the assumption that the physical
connection is still there.
Related
I have an old intranet website written with vb.net and using Oracle.ManagedDataAccess mostly doing read operations from Oracle database 11g.
My db connection code is as follows.
Public Shared Function MyDBConnection(ByVal command_text As String, ByVal connstring As String, ByVal ParamArray parameters As OracleParameter()) As DataTable
Dim OraCommand As New OracleCommand
Dim tmp As New DataTable
Using ORAconnection = New OracleConnection(ConfigurationManager.ConnectionStrings(connstring).ConnectionString)
OraCommand.CommandText = command_text
If parameters IsNot Nothing AndAlso parameters.Length > 0 Then
For Each p In parameters
OraCommand.Parameters.Add(p.ParameterName, p.OracleDbType, p.Size).Value = p.Value
Next p
End If
OraCommand.Connection = ORAconnection
Try
ORAconnection.Open()
tmp.Load(OraCommand.ExecuteReader())
Catch ex As OracleException
End Try
End Using
Return tmp
End Function
And my oracle connection string is like this
<add name="ConnectionString" connectionString="User Id=userid;Password=userpadd;Data Source=servername:port/port_dp"/>
I was testing if my connections to the database were closing properly but it looks like connections on the database stayed open after being closed on my code. Eventually they close way after my query completed about 2 minutes, 10 minutes or hours later.
Is this connection pooling at work? or if there is something wrong with my code?
After reading about oracle pooling, it looks like the application should be reusing the same opened connection on the DB but in my case it looks like is opening new connections anyway.
So my question is, should I disable pooling on my connection string to make sure all connections open/close and not have connections lingering on the DB?
No, you should not disable connection pooling. In .NET connection pooling is managed by a mechanism outside of your reach, and you should proceed as if it is not there: open and close your connections as you normally would (i.e. at the beginning and end of every set of operations that you wish to enroll in a transaction/every set of ops that defines a good "unit of work" such as running a report, updating a table etc
The action of opening and closing connections in your code simply leases the from/returns them to the pool. .NET will manage the rest regarding maintaining a cache of some open connections to the db
Yes, there's pooling. The number of connection might have to do with the default value of min and max pool size. Also, OracleCommand does have a Dispose method that you are not calling.
Added: I see your empty catch statement, you don't need it when using "Using" (or ever). The Dispose will still be called if there's an exception.
I am trying to run a non query using a Oracle connection in ASP C# with CLR 4.5. Here is my code:
string connectionString = ConfigurationManager.ConnectionStrings["OracleConnectionString1"].ConnectionString;
OracleConnection conn = new OracleConnection(connectionString);
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "update SALES_ADVENTUREWORKS2012.SALESORDERDETAIL set UNITPRICEDISCOUNT=0 where ROWGUID='4A399178-C0A0-447E-9973-6AB903B4AECD'";
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = QUERY_TIMEOUT;
int row_affected = cmd.ExecuteNonQuery();
HttpContext.Current.Response.Write("Rows affected:" + row_affected + "<br/>");
conn.Close();
when I run the query in oracle development tool, it works fine.
when I use the asp code above, it freezes when performing the query. It freezes forever even though I used a 5 second timeout.
I've tried using the managed and unmanaged oracle libraries; both behave the same.
Note that using the fill or scalar query work perfectly fine so there is nothing wrong with my connection string. Also the fact that oracle development can perform this update query proves that this is not a permission problem.
Any ideas?
Most likely your query is waiting to get access to the record. You probably have modified that row in "oracle development tool" and have not committed or rolled back that transaction.
Just commit/rollback in your tool or close open session.
You can check for open transactions in v$transaction view.
More on automatic locks in Oracle:
http://docs.oracle.com/cd/E11882_01/server.112/e41084/ap_locks001.htm
Are you certain you are using the 4.5 library? The 3.5 documentation states that the CommandTimeout property has no effect.
The 4.5 documentation suggests it should work, but the Remarks section doesn't mention the change, which warrants suspicion.
Otherwise, the code you posted doesn't seem to show where you actually set the value of QUERY_TIMEOUT to 5 seconds. If QUERY_TIMEOUT has a value of zero, then any other provider (SQLCommand, for example) would wait indefinitely. As vav suggested, locks from other sources could cause an indefinite wait.
I'm getting an error when running the following code thru an ASP/ C# .NET page:
SELECT 1 FROM [database].INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE='BASE TABLE' AND TABLE_NAME='example_table'
The code runs perfectly when I run it in the sql management studio query window.
It's also only broken for 1 specific server - when I run on a different server with a different connection string, it works fine.
I've scoured the internet, and all I can seem to find as an answer is that there are issues with case sensitivity, but I'm using all uppercase, and the table in question is using SQL_Latin1_General_CP1_CI_AS collation anyway.
Based on all this, I'm pretty sure it's some kind of permissions issue, but I'm not really sure where to look.
The error I'm getting:
Invalid object name 'database.INFORMATION_SCHEMA.TABLES'.
The connection string:
<add name="connectionName" connectionString="Data Source=servername; Initial Catalog=master; User ID=user; Password=pw" providerName="System.Data.SqlClient"/>
UPDATE:
Some more information: I had adapted this code from some older VB stuff that basically does the same thing. The VB code runs the same exact query on the same servers and databases, but it works.
The VB code:
Dim connStr As String = ConfigurationManager.ConnectionStrings("connectionName").ConnectionString
Dim objConnection As SqlConnection = New SqlConnection(connStr)
Dim objCommand As SqlCommand = New SqlCommand("SELECT 1 FROM [database].INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND TABLE_NAME='example_table'", objConnection)
objCommand.CommandType = CommandType.Text
objConnection.Open()
The C# and VB code both use the exact same connection string from web.config, so I suppose that leads me to doubt that it would be a permissions issue. Still no clue what the problem is though.
It's a copy paste issue in your case I hope, change the [database] with your DB name.
After a bunch more debugging, I was able to determine that the code was actually running on the wrong server. So, not really any way to find the bug based on what I'd posted, but I think Tony was on the right track based on the back-and-forth.
I'm using an Asp.NET Web Application with MSSQL Server.
In my page i open a connection and i close it at the end of page.
But in Sql Analyzer the Sql session is still there, giving me after some amount of time a connection pool limits exceed error.
Sessions are cleared only when i shutdown the webserver.
Can someone explain how to fix this?
Thanks
This is the code i'm using:
Conn = new SqlConnection(StrConn);
Conn.Open();
.....
Conn.Close(); // In the debugger i can see connection state = closed
Conn = null;
This appears to be a connection pooling issue.
Add Pooling=false to the connection string, and the database won't keep the connection open.
I'm having a strange problem with IIS, asp.net and ODBC.
My application is driven by SQL server via ODBC driver (I know it's bad practice, but my entire DAL is already written and will not be changed).
The problem is that when I run an SP with my web interface, on any other computer other than the production server it works fine, but on the production server I get the following error:
Exception Message: System.Data.Odbc.OdbcException (0x80131937): ERROR [42000] [Microsoft] [ODBC SQL Server Driver][SQL Server]Error converting data type nvarchar to int
Obviously when I run it under management studio it works fine.
I think the problem is somewhere between the IIS and the odbc driver, but I'm not sure exactly where.
I'm running .net framework 4.
This is the calling method:
ODBCComm command = new ODBCComm();
command.Query = "SP_web_update_calls_dest #id=?,#name=? ,#ivrCode=?,#DDI=?,#destType=?,#trkGroup=?,#result=? output";
command.AddInputParam(id);
return AddParamsAndExecute(name, ivrCode, DDI, destType, trkGroup, command);
it basically wraps arround:
OdbcCommand.ExecuteDirect();
Thanks a lot,
Yuval.
I believe your first param is being used in the ID spot. I'm not sure why this would work in pre-production and fail only in production, but try this instead...
ODBCComm command = new ODBCComm();
command.Query = "SP_web_update_calls_dest #id=?,#name=? ,#ivrCode=?,#DDI=?,#destType=?,#trkGroup=?,#result=? output";
return AddParamsAndExecute(id, name, ivrCode, DDI, destType, trkGroup, command);
I have no idea what ODBCComm is or what AddParamsAndExecute does because you haven't included the relavant code, however, here's what the request should look like:
OdbcCommand Cmd = new OdbcCommand("SP_web_update_calls_dest", _Connection);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.Parameters.Add("#id", OdbcType.Int);
Cmd.Parameters["#id"].Value = id;
Cmd.Parameters.Add("#name", OdbcType.NVarChar);
Cmd.Parameters["#name"].Value = name;
Cmd.Parameters.Add("#ivrCode", OdbcType.Int);
Cmd.Parameters["#ivrCode"].Value = ivrCode;
Cmd.Parameters.Add("#DDI", OdbcType.VarChar);
Cmd.Parameters["#DDI"].Value = DDI;
Cmd.Parameters.Add("#destType", OdbcType.Int);
Cmd.Parameters["#destType"].Value = destType;
Cmd.Parameters.Add("#trkGroup", OdbcType.Int);
Cmd.Parameters["#trkGroup"].Value = trkGroup;
Cmd.Parameters.Add("#result", OdbcType.Int);
Cmd.Parameters["#result"].Direction = ParameterDirection.Output;
Cmd.ExecuteNonQuery();
int result = (int)Cmd.Parameters["#result"].Value;
OK,
I think I solved it.
There were actually 2 problems, and I'm not exactly sure what caused them.
Anyway, I switched the ODBC driver to SQL Server Native Client 10.
This basically solved the problem, but for some reason it doesn't support the output modifier in queries so I had to remove that.
So I got it solved, but still have no idea what caused the problem. I'm guessing it has something to do with different versions of drivers.