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.
Related
We have a SQL Server Agent job that runs every hour. Twice a month, the server is rebooted for Microsoft patching. The reboot is done by a different department, so we only know that it will occur during a 4 hour window on a specific day. When the server comes back up, is there a way to make any jobs that didn't start during this time frame autostart?
To my knowledge, there is no "built-in" way. But maybe you could do another job, that checks the last restart date of SQL Server.
SELECT sqlserver_start_time FROM sys.dm_os_sys_info
Then, if it detects that the server was restarted not long ago, it could check when your job ran last time.
select j.job_id, name, last_run_date, last_run_time, last_run_outcome, last_run_duration
from msdb.dbo.sysjobs as j (NoLOCK)
inner join msdb.dbo.sysjobservers as s (NOLOCK) on s.job_id = j.job_id
where enabled=1
And if necessary, tell SQL to start the job immediately
EXEC msdb.dbo.sp_start_job N'YourJobName'
The sp_procoption system stored procedure can be used to run one (or multiple) user defined stored procedures upon the SQL Server service starting. A stored procedure must be created in the master database to be used by this system SP. You can then create a stored procedure that queries the msdb tables for specific (or any as described in your post) jobs that are inactive and then use sp_start_job to run the associated job. The scan for startup procs server configuration option must be enabled to use sp_procoption, however executing this stored procedure automatically enables this which you can verify using sp_configure. An example of adding a stored procedure to execute when the SQL Server service starts via sp_procoption is below.
USE [master]
EXEC SP_PROCOPTION #ProcName = 'uspCheckInactiveJobs', #OptionName = 'startup', #OptionValue = 'on';
I'm running a stored procedure right now that will likely take 12 hours to complete, however the exact actual time is unknown. I have another stored procedure that I need to run once the currently running one is finished. Is it possible in SQL Server to schedule something to run, one time, e.g. "after dbo.storedProcedureName completes execution"?
Yesterday I tried the schedule option in SQL Server Agent called "Start whenever the CPU's become idle" but this did not work.
This may be possible with some add-in, or with a loop monitoring running processes, but it isn't really the best way. Instead, you should set up an SQL Script to run the two in sequence, e.g.:
EXEC dbo.MyLongRunningProc;
EXEC dbo.MyOtherProc;
These are guaranteed to run in sequence, one right after the other, when run from inside SSMS or a similar tool.
You can create and execute (or schedule) a procedure that runs both
create procedure runBothInOrder
as
begin tran
exec procedure1
exec procedure2
commit
I have a report running against a Data Driven subscription in SSRS. The subscription runs a report and produces PDFs - about 1000 of them. The process takes about 2 minutes to complete.
I have been kicking this off manually using the following SQL:
EXEC msdb.dbo.sp_start_job #job_name = '<job_name>'
This works, but what I would like to know is when the job has finished. According to what I have read so far, I should be able to run:
exec msdb.dbo.sp_help_job
This lists my job, but it always has a status of 4 (Idle), even while I can see that reports are being produced.
How can I tell when the job has completed and all my reports have been produced?
MSDB shouldn't contain informtaion on the reporting server. The reporting server is seperate from Sql Server Management Server and will only tell you if the job ran or not not what happened in the job. If you have access to the DB I don't know how you have it set up but I have a subscriptions table that I can check with email sent and when it was sent. IF you don't have that you can go onto the reportserver web site and check the subscription and check the status and it should have a date of when it was last sent.
The only way you can access the information in Sql Server Management Studio is by queryng the DB and its tables assuming it is setup correctly.
I've been developing an application that displays graphs on a website by reading from a SQL Server. Since some of the tables are very large, my SQL scripts take a couple minutes to execute, so I devised a plan to get around this by having a job execute on a monthly basis. I have my T-SQL scripts that process the data and other scripts to create and display the graphs, so the hard part is done. The problem I'm having is creating a scheduled job in SQL Server 2005 (cant upgrade since it's a work computer).
I've been having a great deal of trouble as it seems I don't have the stored procedures installed necessary to create a job or schedule. For example, when I ran:
USE TEST1 ;
GO
EXEC sp_add_job
#job_name = N'MY_FIRST_JOB2' ;
GO
EXEC sp_add_jobstep
#job_name = N'MY_FIRST_JOB2',
#step_name = N'Set database to read only',
#subsystem = N'TSQL',
#command = N'SELECT * FROM [TEST1].[dbo].[BACK1]',
#retry_attempts = 5,
#retry_interval = 5 ;
GO
I received errors saying the stored procedures sp_add_job and sp_add_jobstep could not be found. I tried putting [dbo] before the stored procedures and it didn't help. When I checked my Programmability -> Stored Procedures -> System Stored Procedure folder, there were a lot but none for jobs or scheduling! Interestingly, when I ran
SELECT * FROM [sys].[procedures];
I got nothing, not a single row other than the column headers.
When I tried using the interface in SQL Server Agent, I'm able to create a job and set the schedule but it's not executing. When I open the job, the last executed box doesn't always update even though it should have executed. Furthermore, in the view history/logs, only a few of my attempts appeared (all errored out) for different reasons, some were due to permission even when I set the user to NT AUTHORITY\SYSTEM.
This brings me to 2 questions:
1) Is there a way I can download these stored procedures?
2) Is there any other way I can do this? I have access to SQLExpress but since it doesn't have scheduling and the SQL Server Agent, I opted out and chose the easier route.
I've been at this for a while and am at wits end.
The problem is that the stored procedures you are referencing are not part of the database. All of the job related system stored procedures are in the msdb database.
An example of a proper call would be:
EXEC msdb.dbo.sp_add_job
#job_name = N'MY_FIRST_JOB2';
So we've got a bunch of apps running on our SQL servers, and today we realised that a number of them had a bunch of Partition Schemes/Functions that we didn't create.
The partition schemes and functions were called ifts_comp_fragment_data_space_{hash} and ifts_comp_fragment_partition_function_{hash} respectively.
Digging deeper, we realised that they are marked as system entries (is_system set to 1 in sys.partition_schemes) which means we can't even delete them.
After some research we found out that SQL server will create them to partition the fulltext catalogs if they become too large, or something like that see here. The problem is - we just deleted all the catalogs, and these were left abandoned, with NO way of clearing them out.
I wouldn't worry too much, except I NEED to delete them, since I'm trying to export our DB as a .bacpac file, and that crashes complaining that the DB contains partition schemes/functions and they're not supported.
Is there ANY way of forcing the SQL server to drop those objects, or any other alternative that I could do?
You can change that is_system flag from 1 to 0 and then drop the partition scheme like any other. To do this:
First allow updates on your server:
exec sp_configure 'allow updates', 1
go
reconfigure with override
go
Shutdown your SQL server
Start it back up in Single User mode by running "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn\sqlservr.exe -m" from a console with elevated privs.
Login to the server using the SQL Server DAC http://technet.microsoft.com/en-us/library/ms178068(v=sql.105).aspx
If we do an SP_HELPTEXT on the sys.partition_schemes view, you'll see that the is_system column is based on a status flag in the sys.sysclsobjs table. "sysconv(bit, o.status & 0x4) AS is_system,"
So to change the flag, we have to look at what the current value of the status is and unmark the 4 bit. My value was 4 so I updated it to 0.
update sys.sysclsobjs set status = 0 where name =
'ifts_comp_fragment_data_space_033D368C'
Now you can shutdown the single user mode SQL Server process by just closing your console window and start your sql server windows service. Then just login as you normally would and drop the partition scheme.
Finally, set your 'allow updates' setting back to 0.
This might need to be planned downtime for a production server.
DISCLAIMER This probably isn't a Microsoft supported way of doing this, you may want to test on some non-prod servers before diving in.