Blog Post

SQL Server – Marking a stored procedure as system object

,

Marking a stored procedure as system object allows to run the procedure in a user database context. There are two requirements to allow running a procedure created in [master] database in user database context:

 

1. The stored procedure name must begin with "sp_" :

A stored procedure created with "sp_" prefix can be used in any user database without specifying database/schema. But, the procedure still run in the context of master database and not the user database. Let’s create a procedure to test this:

USE   [master]

GO

 

CREATE PROCEDURE sp_Objects

AS

SELECT      name, object_id, type_desc

FROM        sys.objects

WHERE       is_ms_shipped <> 1

GO

 

– Execute procedure in [master]

SELECT DB_NAME() 'Current Database'

EXEC sp_Objects

 

– Execute procedure in [SqlAndMe]

USE   [SqlAndMe]

 

SELECT DB_NAME() 'Current Database'

 

EXEC sp_Objects

Result Set:

Current Database

——————–

master

 

(1 row(s) affected)

 

name                 object_id            type_desc

————–       —————-     ——————–

sp_who_blocked       1291151645           SQL_STORED_PROCEDURE

sp_Objects           1531152500           SQL_STORED_PROCEDURE

 

(2 row(s) affected)

 

Current Database

——————–

SqlAndMe

 

(1 row(s) affected)

 

name                 object_id            type_desc

————–       —————-     ——————–

sp_who_blocked       1291151645           SQL_STORED_PROCEDURE

sp_Objects           1531152500           SQL_STORED_PROCEDURE

 

(2 row(s) affected)

As you can see from the result set, the procedure sp_Objects runs under [master] even after switching the database using "USE DB".

 

2. The stored procedure must be marked as system object explicitly:

You can mark a stored procedure as system object using sys.sp_MS_marksystemobject system procedure. Let’s mark our procedure sp_Objects as system object and re-execute above code.

Below code will mark the procedure as system object:

USE [master]

 

EXEC sys.sp_MS_marksystemobject sp_Objects

 

You can verify if the object is marked as system object:

USE   [master]

 

SELECT      name, is_ms_shipped

FROM        sys.objects

WHERE       name = 'sp_objects'

Result Set:

name          is_ms_shipped

———–   ————–

sp_Objects    1

 

(1 row(s) affected)

 

sp_Objects is now marked as system object and can be run in user database context:

– Execute procedure in [master]

USE   [master]

SELECT DB_NAME() 'Current Database'

EXEC  sp_Objects

 

– Execute procedure in [SqlAndMe]

USE   [SqlAndMe]

SELECT DB_NAME() 'Current Database'

EXEC  sp_Objects

Result Set:

Current Database

——————–

master

 

(1 row(s) affected)

 

name                 object_id            type_desc

————–       —————-     ——————–

sp_who_blocked       1291151645           SQL_STORED_PROCEDURE

 

(1 row(s) affected)

 

Current Database

——————–

SqlAndMe

 

(1 row(s) affected)

 

name                 object_id            type_desc

————–       —————-     ——————–

LastNames            21575115             USER_TABLE

Customer             62623266             USER_TABLE

Employees            165575628            USER_TABLE

 

(64 row(s) affected)

 

 

You can also create tables in master database which begin with prefix "sp_", and these can be used in user databases without database/schema prefix. It does not need to marked as system object. Try below example yourself:

– Create Table in [master]

USE   [master]

GO

SELECT DB_NAME() 'Current Database'

CREATE TABLE sp_Table1

(

      Col1 CHAR(10)

)

 

INSERT INTO sp_Table1

VALUES ('Master')

 

 

– Insert/Select from [SqlAndMe]

USE   [SqlAndMe]

SELECT DB_NAME() 'Current Database'

INSERT INTO sp_Table1

VALUES ('SqlAndMe')

 

SELECT      *

FROM  sp_Table1

 

 

Hope This Helps! Cheers!

Reference : Vishal (http://SqlAndMe.com)

Filed under: SQLServer

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating