Continue to run a SQL query after the connection closes - sql-server

In SQL Server, is it possible to call a long-running stored procedure, close the connection and let it finish? I don't care about the result. Essentially I want to say "Hey SQL, do this work on your own server."
I want to avoid having to make some service to sit with the open connection and wait for it.

You'll want to use BeginExecuteNonQuery(AsyncCallback, Object), and then have a callback method that effectively does nothing. It's worth mentioning that the connection won't actually be closed, however.
MSDN SqlCommand.BeginExecuteNonQuery Method
Alternatively, you could use Service Broker to queue the request to run a stored procedure. There's a fair bit of plumbing to set up, though. It might not be worth it in your situation. Especially if you aren't using Service Broker for anything else. The advantage here is that the connection can be closed immediately after queuing with Service Broker, and placing messages into a queue is a very quick operation.

You could also use a SQL Agent job to run the procedure that has no schedule, then issue a SQL command to start the job with "EXEC msdb.dbo.sp_start_job #job_name = ''" If you have to change the command frequently it may not be ideal, but that can be done through SQL calls if needed.

Related

Offline and online execution problem with multiples queries incoming

I have a SQL Server service and multiple Windows Service doing some backgrounds work on same server.
One of them (I'm calling it "A") have a routine executing "single_user/offline" and "online/multi_user" to active databases to do some backup operations at midnight. The another ones executes multiple queries over that databases (I'm calling it "B").
The problem is the following:
1.- Windows Service "A" executes SET ONLINE.
2.- Windows Service "B" executes a random SELECT.
3.- Windows Service "A" tries to execute SET MULTI_USER. This execution is dropped because there is an active connection made from Windows Service "B".
I've tried executing SET ONLINE and SET MULTI_USER on same CommandText of the SqlCommand, but this doesn't denies the incoming query from Windows Service "B", breaking my process and keeping the database locked (because the SINGLE_USER).
How can I make an ONLINE and MULTI_USER commands at same time on the Windows Service "A" to make Windows Service "B" being cancelled or wait the process finished? (It's not a problem that Windows Service "B" being cancelled)
Could be sp_dettach_db or sp_attach_db useful?
It sounds like Service A is closing it's connection after bringing the database into Single User mode. This frees up Service B to become the single user, at which point Service A can no longer change the mode until it can grab the single connection back, which it won't be able to do as long as Service B, or any other client for that matter, has it.
I can think of a couple of things you could do here:
Once your offline operations are complete, begin polling until Service A can become the single user again
Find the SPID of the connection from Service B and kill it.
See the limitations and restrictions section about single user mode at this link for more info.
Thanks to all, but I reanalyzed the problem I was having from the beginning, and concluded that the action "SET SINGLE_USER" was not necessary, since the process does not require actions in that mode, so finally with the action "SET OFFLINE" and "SET ONLINE" could prevent intermediate connection problems.

How to stop a running query?

I use RODBC to send queries to an SQL-Server. Sometimes they take too much time to run, so I need to cancel them.
Clicking the red "stop" button in RStudio yields this error message:
R is not responding to your request to interrupt processing so to stop
the current operation you may need to terminate R entirely.
Terminating R will cause your R session to immediately abort. Active
computations will be interrupted and unsaved source file changes and
workspace objects will be discarded.
Do you want to terminate R now?
And if I click yes my session is indeed terminated. (note: using Rgui instead of RStudio doesn't make things better)
However:
when I use another software (named "Query ExPlus") to connect to this same SQL-Server, I have a similar stop button, and clicking it instantly interrupts the query, without any crash.
when I connect to a PostgreSQL database using the RPostgres package I can also interrupt the query at any time.
These two points lead me to think that there should be a way to solve my problem. What can I do?
So far my workaround is:
library(RODBC)
library(R.utils)
withTimeout(mydf <- sqlQuery(myconnection, myquery), timeout=120)
Note: I don't have permission to kill queries from the database side.
I've just stumbled upon the odbc package. It allows to interrupt a query at any time.
Basic usage goes like this:
library(DBI)
myconnection <- dbConnect(odbc::odbc(),
driver = "SQL Server",
server = "my_server_IP_address",
database = "my_DB_name",
uid = "my_user_id",
pwd = "my_password")
dbGetQuery(myconnection, myquery)
I don't have a deep understanding of what happens behind the scenes, but for what I've seen so far in my personal use this package has other advantages over RODBC:
really faster
get the column types from the DB instead of guessing them (see here)
no stringsAsFactors and as.is arguments necessary
Most SQL Server users use SQL Server Management Studio (which is free and can be downloaded from Microsoft) to connect to SQL Server or execute commands from the command line via a tool called SQLCMD.
If you can determine the session id that the SQL Command is being run in you can kill the session which would stop any executing command(s). SQL Server will still need time (could be a 'long' time) to rollback any changes made during the execution of the command.
Terminating a session (depending on the software) can take a while to communicate to SQL Server that the session has been terminated. When I connected to DB2 from SQL Server using linked servers DB2 would buffer the terminate command and it would frequently take up to an hour for DB2 to realize the session had been terminated.
To determine what the session you are running in you can try:
select ##spid;
once you have the spid (lets say 86)
you can then issue (depending on if you have permission to do so)
kill 86;
but as Microsoft notes:
Terminates a user process that is based on the session ID or unit of work (UOW). If the specified session ID or UOW has a lot of work to undo, the KILL statement may take some time to complete, particularly when it involves rolling back a long transaction.
Try to close your "tab query" on SQL Server Management Studio
Then it will appear pop-up,
This Query is currently executing. Do you want to cancel this query ?
Cancel anyway, choose "yes".
try to set your connection prior to query:
sql = odbcConnect('Database name')
Then use same line to run your query:
mydf <- sqlQuery(sql, " myquery ")
Note: The running time is dependant on both database and R server but setting up the connection this way should resolve termination problem.

Problems in Executing the SP which has while(true) loop in SQL SERVER

I know it is not good way and may have many issues. But can anyone tell what are the problems in executing the SP which has while loop.
CREATE PROC udpParseData
BEGIN
WHILE(true)
BEGIN
--logic goes here
END
END
EXEC udpParseData
I want to run it like a service. Instead of running a service which check the DB continuously using SQL Dependancy. Any problem with this and also i have a main concern that how to stop the running SP udpParseData. One more option i have is run the same SP in Scheduler JOB. I wanted to know the restrictions and disadvantages of using this.
You don't want to do this - even a Windows service doesn't work like that. A Windows service would leverage a Timer that wakes up on an interval and starts the message pump.
Write the work you want to execute in a stored procedure and then create a Job on the SQL Server that executes that stored procedure, and setup the times you want it to run. The Job takes the place of the Timer in the Windows service.

Send message from SQL Server trigger

I need to signal a running application (Windows service) when certain things happen in SQL Server (2005). Is there a possibility to send a message from a trigger to an external application on the same system?
You can use a SQL Service Broker queue to do what you want.
The trigger can create a conversation and send a message on the queue.
When it starts, the external process should connect to the database and issue a WAITFOR (RECEIVE) statement on this queue. It will receive the message when the trigger sends it.
Not sure DBA's would approve of this, but there is a way to run commands using xp_cmdshell
"Executes a given command string as an operating-system command shell and returns any output as rows of text. Grants nonadministrative users permissions to execute xp_cmdshell."
Example from MS's site:
CREATE PROC shutdown10
AS
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down
in 10 minutes. No more connections allowed.', no_output
EXEC xp_cmdshell 'net pause sqlserver'
WAITFOR DELAY '00:05:00'
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server shutting down
in 5 minutes.', no_output
WAITFOR DELAY '00:04:00'
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down
in 1 minute. Log off now.', no_output
WAITFOR DELAY '00:01:00'
EXEC xp_cmdshell 'net stop sqlserver', no_output
Either:
Use RAISERROR (severity 10) to fire a SQL agent alert and job.
Load a separate table that is polled periodically by a separate mail handling process. (as HLGEM suggested)
Use a stored procedure to send the message and write to the table.
Each solution decouples the transactional trigger from a potentially long messaging call.
You can send an email from a trigger, but it isn't a recommended practice becasue if the email ssystem is down, no data changes can be made to the table.
Personally if you can live with less than realtime, I would information about the event you are interested in to another table (so the real change of data can go smoothly even if email is down for some reason.) Then I would have a job that checks that table every 5-10 minutes for any new entries and emails those out.
You can use a dbmail email message. It should not slow the trigger down if the mail server is down because the message is queued and then sent by and external (to sql) process.
The table idea sounds good if the application can access sql server.
You could also give access to that same table via sql 2005 native XML Services - which exposes procs through xml.
http://msdn.microsoft.com/en-us/library/ms345123(SQL.90).aspx
Depending on what sort of message you want to send, you could use a CLR stored procedure to connect to a socket on the running process and write the message to that. If you have no control over the process (i.e. can't modify it) you could build a bridge or use a library that can issue a message in a suitable format.
For reliable delivery, you could do something that uses MSMQ to deliver the message.
A reminder that triggers can be problematic for stuff like this because they are embedded in set-operations. And being associated with tables, they aren't very sensitive to the context in which they are fired. The problem can be if they fire on an operation that involves multiple rows, because it's hard to avoid invoking as many instances of your action as there are records in the operation. Several hundred emails are not unlikely, for instance.
Hopefully "things that happen" can be detected in closer association with the context in which they happen (which also can be interesting to try to backtrack from a trigger.)

Best Method to Spawn Process from SQL Server Trigger

How would I go about spawning a separate process using a SQL Server 05/08 trigger? Ideally, I would like to spawn the process and have SQL Server not wait on the process to finish execution. I need to pass a couple parameters from the insert that is triggering the process, but the executable would take care of the rest.
a bit of CLR Integration, combined with SQL Service Broker can help you here.
http://microsoft.apress.com/feature/70/asynchronous-stored-procedures-in-sql-server-2005
you want to use the system stored procedure xp_cmdshell
info here: http://msdn.microsoft.com/en-us/library/ms175046.aspx
I saw that particular article, but didn't see an option to 'spawn and forget'. It seems like it waits for the output to be returned.
xp_cmdshell operates synchronously. Control is not returned to the caller until the command-shell command is completed.

Resources