SQL Server Agent: How to "sleep"? - sql-server

In a scripting step in a scheduled task in SQL Server Agent 2005, I need to trigger a webscript that is running on a different server. I'm doing this:
Dim ie
Set ie = CreateObject( "InternetExplorer.Application" )
ie.navigate "...to my dreamscript"
' Wait till IE is ready
Do While ie.Busy
(1)
Loop
ie.Quit
set ie = Nothing
At (1) I would like to "sleep" (e.g. WScript.sleep(..)), but WScript is not available in this environment. Is there another way to "sleep" for a while?

If you're only trying to have the SQL SErver Agent task that waits for a time period use a T-SQL Task with the script
WAITFOR DELAY '01:00:00' -- wait for an hour
and change the time to the duration that you'd like to wait.
HTH
Andy

You can write a console applicaton and execute the console app in SQL agent job.

You could execute the wscript by using a SQL Server Agent task with a type of "Operpating System (CmdExec)". This requires that xp_cmdshell be enabled and it is often disabled (by default) due to security concerns. However, it does allow you to initiate programs, such as wscript, that are run at the command prompt.
You could move the code into SQLCLR where you can write a stored procedure in C# or VB.Net. The VB.Net SQLCLR Code would be pretty similar to your original wscript.

Related

(SQL) Server Agent Job not stopping

I am using SQL Server 2016, and have some Jobs running in the SQL Server Agent. Today I found one of the job is taking too long (10hours!) to run and is still processing, so I try to stop that. I tried right-click and stop the job, it showed a success message. However, when I go to the Job Activity Monitor, it is showing that the job is still running! I also tried the following code:
USE [msdb]
GO
EXEC dbo.sp_stop_job N'Process Reserving MI (except problematic tables)'
GO
It also says the job stopped successfully. But again when I go to the Job Activity Monitor, it is showing that the job is still running!
Can any one please help?
At the end I have to ask the server team to reboot the server in order to solve this problem

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.

SSIS SQL Server agent launch job already running

Is there any way to have a package (which will be a wrapper) run every minute in SQL Server agent, even if it is already running from a previous execution. It seems the SQL Server agent does not launch if already running. Is there a way to override this behaviour?
I wanted to do something such as
Wrapper.dtsx
--> read from table of packages to run, and select next in line
--> execute package task with the package dynamically set from previously
selection
--> exit
ie
table has the following packages (assume some ranking will exist eventually)
a.dtsx (say runs for 5 mins)
b.dtsx (say runs for 4 mins)
c.dtsc (say runs for 6 mins)
12:01 am a.dtsx is executed
12:02 am b.dtsx is executed
12:03 am c.dtsx is executed
at the moment I can only get the following to occur
12:01 am a.dtsx is executed
12:06 am b.dtsx is executed
12:10 am c.dtsx is executed
Hm, this SQL Jobs behavior is standard for MS SQL Server and cannot be altered. For your situation if you are on SQL 2012 and higher, you can use new SSIS Catalog with async execution. By using this your job will start package execution and quit; therefore you are free to start it in a minute. Disadvantage - job status will only show whether package been started and nothing on its outcome; you have to do execution monitoring yourself.
Switching to async package execution requires SSIS 2012+, establishing SSIS Catalog DB, switching your packages to Project deploy model. After all, create SQL Job to start package, specify all needed connections and parameters, save it. Then with context menu select Script Job as -> DROP and CREATE to -> New Query Editor Window. In the query text - locate substring
/Par "\"$ServerOption::SYNCHRONIZED(Boolean)\"";True
and switch it to
/Par "\"$ServerOption::SYNCHRONIZED(Boolean)\"";False
Then run script updating your job.
This strange script manipulation is needed since by default SQL Job executes package synchronously and does not expose async option in user interface.

SQL Server job timeout

So, it seems that it is not possible to set the timeout for each single step in a SQL Server job (article from StackExchange).
MSDN points out that you can of course set the Agent timeout:
Sql Server Agent properties.
Set Job execution shutdown.
Questions
How does Agent time-out work?
Is there any other way (preferably by configuration) to setup the single step timeout?
Is there any other way (preferably by configuration) to setup the whole job timeout?
To answer question 2, I'm not sure if this is the best option but you could use OPENROWSET to control a single step timeout.
http://msdn.microsoft.com/en-us/library/ms190312.aspx
Just because OPENROWSET is normally used to access remote servers doesn't mean it has to be.
Probably this is similar to how agent timeout works.
You could even use this to control the whole job timeout although if you want to do it by configuration you'd have to create your own tables.
I'm not sure this is the best solution but it's a solution at least.

Scheduled run of stored procedure on SQL server

Is it possible to set up somehow Microsoft SQL Server to run a stored procedure on regular basis?
Yes, in MS SQL Server, you can create scheduled jobs. In SQL Management Studio, navigate to the server, then expand the SQL Server Agent item, and finally the Jobs folder to view, edit, add scheduled jobs.
If MS SQL Server Express Edition is being used then SQL Server Agent is not available. I found the following worked for all editions:
USE Master
GO
IF EXISTS( SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[MyBackgroundTask]')
AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[MyBackgroundTask]
GO
CREATE PROCEDURE MyBackgroundTask
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- The interval between cleanup attempts
declare #timeToRun nvarchar(50)
set #timeToRun = '03:33:33'
while 1 = 1
begin
waitfor time #timeToRun
begin
execute [MyDatabaseName].[dbo].[MyDatabaseStoredProcedure];
end
end
END
GO
-- Run the procedure when the master database starts.
sp_procoption #ProcName = 'MyBackgroundTask',
#OptionName = 'startup',
#OptionValue = 'on'
GO
Some notes:
It is worth writing an audit entry somewhere so that you can see that the query actually ran.
The server needs rebooting once to ensure that the script runs the first time.
A related question is: How to run a stored procedure every day in SQL Server Express Edition?
Yes, if you use the SQL Server Agent.
Open your Enterprise Manager, and go to the Management folder under the SQL Server instance you are interested in. There you will see the SQL Server Agent, and underneath that you will see a Jobs section.
Here you can create a new job and you will see a list of steps you will need to create. When you create a new step, you can specify the step to actually run a stored procedure (type TSQL Script). Choose the database, and then for the command section put in something like:
exec MyStoredProcedure
That's the overview, post back here if you need any further advice.
[I actually thought I might get in first on this one, boy was I wrong :)]
Probably not the answer you are looking for, but I find it more useful to simply use Windows Server Task Scheduler
You can use directly the command sqlcmd.exe -S "." -d YourDataBase -Q "exec SP_YourJob"
Or even create a .bat file. So you can even 2x click on the task on demand.
This has also been approached in this HERE
I'll add one thing: where I'm at we used to have a bunch of batch jobs that ran every night. However, we're moving away from that to using a client application scheduled in windows scheduled tasks that kicks off each job. There are (at least) three reasons for this:
We have some console programs that need to run every night as well. This way all scheduled tasks can be in one place. Of course, this creates a single point of failure, but if the console jobs don't run we're gonna lose a day's work the next day anyway.
The program that kicks off the jobs captures print messages and errors from the server and writes them to a common application log for all our batch processes. It makes logging from withing the sql jobs much simpler.
If we ever need to upgrade the server (and we are hoping to do this soon) we don't need to worry about moving the jobs over. Just re-point the application once.
It's a real short VB.Net app: I can post code if any one is interested.
You could use SQL Server Service Broker to create custom made mechanism.
Idea (simplified):
Write a stored procedure/trigger that begins a conversation (BEGIN DIALOG) as loopback (FROM my_service TO my_service) - get conversation handler
DECLARE #dialog UNIQUEIDENTIFIER;
BEGIN DIALOG CONVERSATION #dialog
FROM SERVICE [name]
TO SERVICE 'name'
...;
Start the conversation timer
DECLARE #time INT;
BEGIN CONVERSATION TIMER (#dialog) TIMEOUT = #time;
After specified number of seconds a message will be sent to a service. It will be enqueued with associated queue.
CREATE QUEUE queue_name WITH STATUS = ON, RETENTION = OFF
, ACTIVATION (STATUS = ON, PROCEDURE_NAME = <procedure_name>
, MAX_QUEUE_READERS = 20, EXECUTE AS N'dbo')
, POISON_MESSAGE_HANDLING (STATUS = ON)
Procedure will execute specific code and reanable timer to fire again.
You can find fully-baked solution(T-SQL) written by Michał Gołoś called Task Scheduler
Key points from blog:
Pros:
Supported on each version (from Express to Enterprise). SQL Server Agent Job is not available for SQL Server Express
Scoped to database level. You could easiliy move database with associated tasks (especially when you have to move around 100 jobs from one enviromnent to another)
Lower privileges needed to see/manipulate tasks(database level)
Proposed distinction:
SQL Server Agent (maintenance):
backups
index/statistics rebuilds
replication
Task Scheduler (business processes):
removing old data
preaggregations/cyclic recalculations
denormalization
How to set it up:
get source code from section: "Do pobrania" - To download
(enabling broker/setting up schema tsks/configuration table + triggers + stored procedure)/setting up broker things)
set up configuration table [tsks].[tsksx_task_scheduler] to add new tasks (columns names are self-descriptive, sample task included)
Warning: Blog is written in Polish but associated source code is in English and it is easy to follow.
Warning 2: Before you use it, please make sure you have tested it on non-production environment.
Using Management Studio - you may create a Job (unter SQL Server Agent)
One Job may include several Steps
from T-SQL scripts up to SSIS Packages
Jeb was faster ;)
You should look at a job scheduled using the SQL Server Agent.

Resources