How to tell if ADODB CommandTimeout is reached? - sql

I have some VBA that queries a SQL database using ADODB. Currently I have the CommandTimeout set to 30 seconds. If nothing is returned, that can either be because no such record exists in the SQL database, or because the timeout was reached. I would like to be able to distinguish these two cases and display a warning when the timeout is reached. Is there a way to achieve this?

Firstly read this: ADO Event Instantiation: Visual Basic
Check EventStatusEnum for adStatusOK - which should not be set in case TimeOut.
You could also catch up "InfoMessage"
InfoMessage Event to see information like in SSMS when you run query.

Related

Microsoft SQL Server database locks

A lot of times database locks appear on our Microsoft SQL Server database. The blocker query appears as Fetch
API_CURSOR000000000004D888. This string is just a sample. But it is always an API_CURSOR0000000XXXXX some value. We were able to find the SQL query running behind this cursor using steps in articles like
https://www.sqlskills.com/blogs/joe/hunting-down-the-origins-of-fetch-api_cursor-and-sp_cursorfetch/
https://social.msdn.microsoft.com/Forums/en-US/f51618eb-5332-4f10-9985-b343933579da/fetch-apicursor-unusual?forum=sqldatabaseengine
We could find the SQL query that is blocking the database. It looked like this below. Every time it is the same query.
session_id properties creation_time is_open text 200 API | Dynamic | Scroll Locks | Global (0) 05:44.8 1 (#P1 nchar(10))
SELECT *
FROM JDE_PRODUCTION.PRODDTA.F00022 (UPDLOCK)
WHERE (UKOBNM = #P1)
FOR UPDATE OF UKOBNM, UKUKID
I am seeking help here to see if there is a way we can find the actual values that are passed in the variable #P1. Please let me know if someone has ideas or already done this.
no you will not be. rather check with your application team and see how the DB connections are set up.
if its a Docker Image/Container then check the Database URL, there they may have set SelectMethod = Cursor.
with such settings, every query passed via this Connection will make Cursor call to SQL Server which is unnecessary.

How do to increase timeout value for DataGrip's connection to Google BigQuery?

I currently connect JetBrain's DataGrip IDE to Google BigQuery to run my queries. I get the following error however: [Simba][BigQueryJDBCDriver](100034) The job has timed out on the server. Try increasing the timeout value. This of course happens when I run a query that may take some time to execute.
I can execute queries that take a short amount of time to complete so the connection does work.
I looked at this question (SQL Workbench/J and BigQuery) but I still did not fully understand how to change the timeout value
The error is seen below in this screenshot:
This works well also:
Datasource Properties | Advanced | Timeout : 3600
Please open up data source properties and add this to the very end of connection URL: ;Timeout=3600; (note it case sensitive). Try to increase the value until error is gone.

All of a Sudden , Sql Server Timeout

We got a legacy vb.net applicaction that was working for years
But all of a sudden it stops working yesterday and gives sql server timeout
Most part of application gives time out error , one part for example is below code :
command2 = New SqlCommand("select * from Acc order by AccDate,AccNo,AccSeq", SBSConnection2)
reader2 = command2.ExecuteReader()
If reader2.HasRows() Then
While reader2.Read()
If IndiAccNo <> reader2("AccNo") Then
CAccNo = CAccNo + 1
CAccSeq = 10001
IndiAccNo = reader2("AccNo")
Else
CAccSeq = CAccSeq + 1
End If
command3 = New SqlCommand("update Acc Set AccNo=#NewAccNo,AccSeq=#NewAccSeq where AccNo=#AccNo and AccSeq=#AccSeq", SBSConnection3)
command3.Parameters.Add("#AccNo", SqlDbType.Int).Value = reader2("AccNo")
command3.Parameters.Add("#AccSeq", SqlDbType.Int).Value = reader2("AccSeq")
command3.Parameters.Add("#NewAccNo", SqlDbType.Int).Value = CAccNo
command3.Parameters.Add("#NewAccSeq", SqlDbType.Int).Value = CAccSeq
command3.ExecuteNonQuery()
End While
End If
It was working and now gives time out in command3.ExecuteNonQuery()
Any ideas ?
~~~~~~~~~~~
Some information :
There isnt anything that has been changed on network and the app uses local database
The main issue is that even in development environment it donest work anymore
I'll state the obvious - something changed. It could be an upgrade that isn't having the desired effect - it could be a network component going south - it could be a flakey disk - it could be many things - but something in the access path has changed. What other problem indications are you seeing, including problems not directly related to this application? Where is the database stored (local disk, network storage box, written by angels on the head of a pin, other)? Has your system administrator "helped" or "improved" things somehow? The code has not worn out - something else has happened.
Is it possible that this query has been getting slower over time and is now just exceeded the default timeout?
How many records would be in the acc table and are there indexes on AccNo and AccSeq?
Also what version of SQL are you using?
How long since you updated statistics and rebuilt indexes?
How much has your data grown? Queries that work fine for small datasets can be bad for large ones.
Are you getting locking issues? [AMJ] Have you checked activity monitor to see if there are locks when the timeout occurs?
Have you run profiler to grab the query that is timing out and then run it directly onthe server? Is it faster then? Could also be network issues in moving the information from the database server to the application. That would at least tell you if it s SQl Server issue or a network issue.
And like Bob Jarvis said, what has recently changed on the server? Has something changed in the database structure itself? Has someone added a trigger?
I would suggest that there is a lock on one of the records that you are trying to update, or there are transactions that haven't been completed.
I know this is not part of your question, but after seeing your sample code i have to make this comment: is there any chance you could change your method of executing sql on your database? It is bad on so many levels.
Perhaps should you set the CommandTimeout property to a higher delay?
Doing so will allow your command to wait a little longer for the underlying database to respond. As I see it, perhaps are you not letting time enough for your database engine to perform all what is required before creating another command to perform your update.
Know that the SqlDataReader continues to "SELECT" while feeding the in-memory objects. Then, while reading, you require your code to update some other table, which your DBE just can't handle, by the time your SqlCommand requires, than times out.
any chances of a "quotes" as part of the strings you are passing to queries?
any chances of date dependent queries where a special condition is not working anymore?
Have you tested the obvious?
Have you run the "update Acc Set AccNo=#NewAccNo,AccSeq=#NewAccSeq where AccNo=#AccNo and AccSeq=#AccSeq" query directly on your SQL Server Management Studio? (Please replace the variables with some hard coded values)
Have you run the same test on another colleague's PC?
Can we make sure that the SQLConnection is working fine. It could be the case that SQL login criteria is changed and connection is getting a timeout. It will be probably more helpful if you post the error message here.
You can rewrite the update as a single query. This will run much faster than the original query.
UPDATE subquery
SET AccNo = NewAccNo, AccSeq = NewAccSeq
FROM
(SELECT AccNo, AccSeq,
DENSE_RANK() OVER (PARTITION BY AccNo ORDER BY AccNo) NewAccNo,
ROW_NUMBER() OVER (PARTITION BY AccNo ORDER BY AccDate, AccSeq)
+ 10000 NewAccSeq
FROM Acc) subquery
After HLGEM's suggestions, I would check the data and make sure it is okay. In cases like this, 95% of the time it is the data.
Make sure disk is defragged. Yes, I know, but it does make a difference. Not the built-in defragger. One that defrags and optimizes like PerfectDisk.
This may be a bit of a long shot, but if your entire application has stopped working, have you run out of space for the transaction log in your database? Either it's been specified to an absolute size, and that has been reached, or your disk is just full.
May be your tables include more information, and defined SqlConnection.ConnectionTimeout property value in config file with little value. And this value isn't necessary to execute your queries.
you can trying optimize your queries, and also rebuilt indexes.

Session.SetBatchSize does not change the batchsize

I create the Session factory like:
FluentConfiguration cfg =
Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.ConnectionString(
c => c.Is(dbConnectionString)).**AdoNetBatchSize(100)**.ShowSql()).
Mappings(m => m.FluentMappings.AddFromAssembly(mappingAssembly)).
Mappings(m => m.HbmMappings.AddFromAssembly(mappingAssembly));
If I later set
session.SetBatchSize(someOtherSize); during the later program execution
nothing happens. it is as if this command is just a mock.
Why that?
Thanks in advance
I have no idea if and how the NHProf reports batching but using the normal SQL Profiler you cannot notice it.
To verify how it works and if it is indeed enabled as I have set it up, I had to debug the NHibernate's code.
What NHinernate does is to add each generated SQL command in a collection of SQL commands that it is flushed (send to the DB) when the defined BatchSize is reached or when there are no more SQL commands to execute.
Observing the SQL profiler this is not noticable as SQL queries appear but actually NHibernate sends the commands in bactches to the DB.
This way if you want to execute 10 SQL statements without setting the BatchSize NHinerante will talk to the DB 10 times but setting the BatchSize to 10 then it will talk to the DB only once sending the all SQL queries in one go. Unfortunately this is not noticeable in the SQL Profiler...
How are you checking that batching actually occurs and what batch size is being used? SQL profiler does not show batching, you have to use NHibernate Profiler to get a good understanding of what is being batched.
Looking at the NH source session.SetBatchSize() does what it says it does, so it should work :)
Don't forget to set the <property name="adonet.batch_size">3</property> in the config file. The max value, I think is 50. But NH doesn't throw any error if set an higher value and I don't know the default value the.

How to reduce timeout period when sql 2005 database unavailable

I have some ASP (Classic) code that queries a SQL 2005 Express database. I'm currently handling programmatically if this DB goes down by handling the error when someone tries to connect and can't. I capture the error and bypass subsequent db queries to this database using a session variable.
My problem is that this first query takes about 20 seconds before it timeouts.
I'd like to reduce this timeout length but can't find which property either in the code or database is the right one to reduce.
I've tried following in the code;
con.CommandTimeout = 5
con.CONNECTIONTIMEOUT = 5
Any suggestions please?
Thanks,
Andy
First off you should investigate why the DB is going down at all. We manage servers for hundreds of clients and have never run into a problem with the DB going down unless it was scheduled maintenance.
Besides that, you're already onto the right properties.
"Connect Timeout" is set in the connection string and controls how long the client waits to establish a connection to the database. It should be safe to lower this value in most cases--connections should never take long to establish.
"CommandTimeout" is a property on the IDbCommand implementation and controls how long the client waits for a particular query to return. You can lower this value if you know your queries will not take longer than the value you're setting.
Ended up using the "Connect Timeout" option within ADODB.Connection string.
e.g.
Set con = Server.CreateObject( "ADODB.Connection" )
con.Open "Provider=SQLOLEDB;Server=databaseserver;User ID=databaseuser;Password=databasepassword;Initial Catalog=databasename;Connect Timeout=5;"
If Err.Number = 0 And con.Errors.Count = 0 Then
'connected to database successfully
Else
'did not connect to database successfully within timeout period specified (5 seconds in this example)
End If