A SQL Server administrator can create stored
procedures that are marked for execution automatically whenever SQL
Server starts. They are often referred to as startup procedures.
Startup procedures are useful for performing housekeeping-type tasks or
starting up a background process when SQL Server starts. Some possible
uses for startup procedures include the following:
- Automatically perform system or maintenance tasks in tempdb, such as creating a global temporary table.
- Enable
custom SQL Server Profiler traces automatically whenever SQL Server is
running.
- Automatically start other external processes on the SQL Server machine, using xp_cmdshell.
- Prime the data cache with the contents of your critical, frequently used tables.
- Prime
the plan cache by executing procedures or functions you want to have
compiled and cached before applications start using them.
To create a startup procedure, you log in as a system administrator and create the procedure in the master database. Then you set the procedure startup option to true by using sp_procoption:
sp_procoption procedure_name, startup, true
If you no longer want the procedure to run at startup, remove the startup option by executing the same procedure and changing the value to false.
By default, a startup procedure runs in the context of the system administrator, but it can use SETUSER
to impersonate another account, if necessary. If you need to reference
objects in other databases from within a startup procedure, you need to
fully qualify the object with the appropriate database and owner names.
Startup procedures are launched asynchronously; that
is, SQL Server doesn’t wait for them to complete before continuing with
additional startup tasks. This allows a startup procedure to execute in a
loop for the duration of the SQL Server process, or it allows several
startup procedures to be launched simultaneously. While a startup
procedure is running, it runs as a separate worker thread.
Tip
If you need to execute a series of stored procedures
in sequence during startup, you can nest the stored procedure calls
within a single startup procedure. This approach consumes only a single
worker thread.
Any error messages or print statements generated by a
startup procedure are written to the SQL Server error log. For example,
consider the following whimsical but utterly useless startup procedure:
use master
go
create procedure good_morning
as
print 'Good morning, Dave'
return
go
sp_procoption good_morning, startup, true
go
When SQL Server is restarted, the following entries would be displayed in the error log:
2009-06-12 13:21:00.04 spid5s Recovery is complete. This is an
informational message only. No user action is required.
2009-06-12 13:21:00.15 spid5s Launched startup procedure 'good_morning'.
2009-06-12 13:21:00.15 spid51s Good morning, Dave
Any result sets generated by a startup procedure
vanish into the infamous bit bucket. If you need to return result sets
from a startup procedure, the procedure should be written to insert the
results into a table. The table needs to be a permanent table and not a
temporary table because a temporary table would be automatically dropped
when the startup procedure finished executing.
The following example is a startup procedure that could preload all tables within the Sales and Purchasing schemas in the AdventureWorks database into data cache memory on SQL Server startup:
use master
go
create procedure prime_cache
as
declare @tablename varchar(128),
@schemaname varchar(128)
declare c1 cursor for
select s.name, o.name
from AdventureWorks.sys.objects o
join AdventureWorks.sys.schemas s
on o.schema_id = s.schema_id
where type = 'U'
and s.name in ('Sales', 'Purchasing')
open c1
fetch c1 into @schemaname, @tablename
while @@fetch_status = 0
begin
print 'Loading ''' + @schemaname + '.' + @tablename + ''' into data cache'
exec ('select * from AdventureWorks.' + @schemaname + '.' + @tablename)
fetch c1 into @schemaname, @tablename
end
close c1
deallocate c1
return
go
sp_procoption prime_cache, startup, true
go
The error log output from this startup procedure would be similar to the following:
2009-06-15 19:39:18.970 spid7s Launched startup procedure 'prime_cache'.
2009-06-15 19:39:20.550 spid30s Loading 'Sales.Store' into data cache
2009-06-15 19:39:20.870 spid30s Loading 'Sales.StoreContact' into data cache
2009-06-15 19:39:20.870 spid30s Loading 'Purchasing.ProductVendor' into data
cache
2009-06-15 19:39:20.950 spid30s Loading 'Purchasing.Vendor' into data cache
2009-06-15 19:39:21.010 spid30s Loading 'Purchasing.PurchaseOrderDetail' into
data cache
2009-06-15 19:39:21.140 spid30s Loading 'Purchasing.VendorAddress' into data
cache
2009-06-15 19:39:21.150 spid30s Loading 'Purchasing.VendorContact' into data
cache
2009-06-15 19:39:21.160 spid30s Loading 'Purchasing.PurchaseOrderHeader' into
data cache
2009-06-15 19:39:21.220 spid30s Loading 'Sales.ContactCreditCard' into data
cache
2009-06-15 19:39:21.310 spid30s Loading 'Sales.CountryRegionCurrency' into
data cache
2009-06-15 19:39:21.420 spid30s Loading 'Sales.CreditCard' into data cache
2009-06-15 19:39:21.540 spid30s Loading 'Sales.Currency' into data cache
2009-06-15 19:39:21.570 spid30s Loading 'Sales.SalesOrderDetail' into data
cache
2009-06-15 19:39:22.040 spid30s Loading 'Sales.CurrencyRate' into data cache
2009-06-15 19:39:22.120 spid30s Loading 'Sales.Customer' into data cache
2009-06-15 19:39:22.420 spid30s Loading 'Sales.SalesOrderHeader' into data cache
2009-06-15 19:39:23.170 spid30s Loading 'Sales.CustomerAddress' into data
cache
2009-06-15 19:39:23.290 spid30s Loading 'Sales.SalesOrderHeaderSalesReason'
into data cache
2009-06-15 19:39:23.340 spid30s Loading 'Sales.SalesPerson' into data cache
2009-06-15 19:39:23.360 spid30s Loading 'Sales.SalesPersonQuotaHistory' into
data cache
2009-06-15 19:39:23.380 spid30s Loading 'Sales.SalesReason' into data cache
2009-06-15 19:39:23.380 spid30s Loading 'Sales.Individual' into data cache
2009-06-15 19:39:23.950 spid30s Loading 'Sales.SalesTaxRate' into data cache
2009-06-15 19:39:23.970 spid30s Loading 'Sales.SalesTerritory' into data cache
2009-06-15 19:39:24.000 spid30s Loading 'Sales.SalesTerritoryHistory' into
data cache
2009-06-15 19:39:24.060 spid30s Loading 'Purchasing.ShipMethod' into data
cache
2009-06-15 19:39:24.090 spid30s Loading 'Sales.ShoppingCartItem' into data
cache
2009-06-15 19:39:24.100 spid30s Loading 'Sales.SpecialOffer' into data cache
2009-06-15 19:39:24.110 spid30s Loading 'Sales.SpecialOfferProduct' into data
cache
If you want to disable the automatic execution of all startup procedures, you can use sp_configure to disable the scan for startup procs configuration option. Setting this option to 0 disables the running of startup procedures on subsequent SQL Server restarts.
If SQL Server is not currently running and you want
to skip running the startup procedures, you can specify Trace Flag 4022
as a startup parameter. You can set the trace flag for a SQL Server
instance by using the SQL Server Configuration Manager. In SQL Server
Configuration Manager, perform the following steps:
1. | Click on SQL Server 2008 Services.
|
2. | In the right pane, right-click the SQL Server instance you want to set the trace flag for and select Properties.
|
3. | Go to the Advanced tab and select the Startup Parameters box.
|
4. | Click the expand arrow to the right of the input field to expand the entire field.
|
5. | Place your cursor at the end of the value and type a semicolon (;).
|
6. | Type -T4022 (see Figure 1).
|
7. | Click OK.
|
Also, if you start SQL Server with minimal configuration (by using the -f flag), the startup stored procedures are not executed.