mssqltips logo

Tutorials          DBA          Dev          BI          Career          Categories          Webcasts          Whitepapers          Today's Tip          Join

Tutorials      DBA      Dev      BI      Categories      Webcasts

DBA    Dev    BI    Categories


Granting View Definition Permission to a User or Role in SQL Server

By:   |   Read Comments (7)   |   Related Tips: More > Views

In SQL Server 2005 by default users of a database that are only in the public role cannot see the definitions of an object while using sp_help, sp_helptext or the object_definition function.  Sometimes this is helpful to allow developers or other non-administrators to see the object definitions in a database, so they can create like objects in a test or development database.  Instead of granting higher level permissions, is there a way to allow users that only have public access the ability to see object definitions?

When issuing sp_help, sp_helptext or using the object_definition() function the following errors in SQL 2005 will occur if the user does not have permissions to the see the object metadata.   Here are a couple of examples of these errors.

EXEC sp_help Customer
Msg 15009, Level 16, State 1, Procedure sp_help, Line 66
The object 'Customer' does not exist in database 'MSSQLTIPS' or is invalid for this operation.

A select against the OBJECT_DEFINITION function will return a value of NULL if the user does not have permissions to see the meta data.

SELECT object_definition (OBJECT_ID(N'dbo.vCustomer'))

By default users were able to see object definitions in SQL Server 2000, but in SQL Server 2005 this functionality was removed to allow another layer of security.  By using a new feature called VIEW DEFINITION it is possible to allow users that only have public access the ability to see object definitions.

To turn on this feature across the board for all databases and all users you can issue the following statement:

USE master

To turn on this feature across the board for all databases for user "User1" you can issue the following statement:

USE master

To turn this feature on for a database and for all users that have public access you can issue the following:

USE AdventureWorks

If you want to grant access to only user "User1" of the database you can do the following:

USE AdventureWorks
GRANT VIEW Definition TO User1

To turn off this functionality you would issue the REVOKE command such as one of the following:

USE master 

-- or

USE AdventureWorks 
REVOKE VIEW Definition TO User1 

If you want to see which users have this access you can issue the following in the database.

USE AdventureWorks

Here are two rows that show where the VIEW DEFINITION action has been granted.  The first on a particular object and the second for all objects in the database.

To take this a step further, if you do not want to grant this permission on all objects the following stored procedure can be used to grant this to all objects or particular objects in a database.  This is currently setup for all object types, but this can be changed by including less object types in the WHERE clause.

WHERE type IN ('P''V''FN''TR''IF''TF''U'

Included Object Types are: 
P - Stored Procedure 
V - View 
FN - SQL scalar-function
TR - Trigger 
IF - SQL inlined table-valued function
TF - SQL table-valued function
U - Table (user-defined)

To use this, you can create this stored procedure in your user databases and then grant the permissions to the appropriate user instead of making things wide open for a user or all users.  Just replace ChangeToYourDatabaseName for your database before creating.

USE ChangeToYourDatabaseName 
CREATE PROCEDURE usp_ExecGrantViewDefinition 
(@login VARCHAR(30)) 
Included Object Types are: 
P - Stored Procedure 
V - View 
FN - SQL scalar-function
TR - Trigger 
IF - SQL inlined table-valued function
TF - SQL table-valued function
U - Table (user-defined)


--Declare @execSQL varchar(2000), @login varchar(30), @space char (1), @TO char (2) 
DECLARE @execSQL VARCHAR(2000), @space CHAR (1), @TO CHAR (2

SET @to 'TO'
SET @execSQL 'Grant View Definition ON ' 
SET @login REPLACE(REPLACE (@login'['''), ']''')
SET @login '[' @login ']'
SET @space ' '

SELECT @execSQL schema_name(schema_id) + '.' [name] @space @TO @space @login 
FROM sys.all_objects s 
WHERE type IN ('P''V''FN''TR''IF''TF''U'

SET @execSQL '' 




PRINT @execSQL --Comment out if you don't want to see the output

EXEC (@execSQL)


GOTO Execute_SQL 




Once this procedure has been created you can grant the permissions as follows. This example grants view definition to a user "userXYZ" in "MSSQLTIPS" Database for all object types that were selected.

EXEC usp_ExecGrantViewDefinition 'userXYZ'

Next Steps

For additional information on the topics discussed refer to these keywords in SQL Server 2005 Books Online:

  • sp_helptext
  • sp_help
  • object_definition
  • Object_Id
  • Create Procedure
  • Schema_Name
  • Schema_ID
  • Replace

Last Update:

About the author
MSSQLTips author Nitin Rana Nitin Rana is a Microsoft Certified Professional and currently has over 12 years of IT experience with the SQL server core components.

View all my tips

More SQL Server Solutions

Post a comment or let the author know this tip helped.

All comments are reviewed, so stay on subject or we may delete your comment. Note: your email address is not published. Required fields are marked with an asterisk (*).

*Name    *Email    Notify for updates 

Get free SQL tips:

*Enter Code refresh code     

Sunday, April 23, 2017 - 8:08:31 AM - Aaronhielp Back To Top
Hello. And Bye.

Wednesday, January 04, 2017 - 4:41:26 PM - sean Back To Top

 This is great. This really helped a lot. No one else really had a real answer to this.


Tuesday, March 03, 2015 - 10:31:00 AM - Srini Back To Top

Very useful article. Thank you very much.


Tuesday, August 28, 2012 - 9:52:24 AM - boris tyukin Back To Top

very nice post that helps to convince DBA team :) apparently many DBAs are not aware of this and think that you need to have exec permissions to view the source code of the objects.

Friday, June 22, 2012 - 5:48:53 AM - Dinesh Vishe Back To Top

SET ANSI_WARNINGS OFFcan we use in View ??

Thursday, January 19, 2012 - 12:44:35 PM - Arvind Back To Top

Hi Nitin,

How are you doing? Nitin I need some help in SQL 2000 for security, can you take a look and see if you can please help me....

Here's what iam looking for :

I want to create a stored procedure in SQL 2000 which will create Role in a database(as per what i pass the name), after creating the role assign permission to that Role, let's say for all tables in a database SELECT permission or Exec to all the proc.

After assigning permission to the Role, we need to attach that Role to a USER in the database.

If you remember HarperCollins structure, here what i'm looking for :

Let's say there is a Login with your name : ITServices\Nitin

Now i need to create a role(from the stored procedure), define Role some permission, let's say the Role name is READER, we need to give SELECT to that ROLE. After its done we need to assign that ROLE to an USER.

I don't know if below code will help you but it will give you and idea of what iam trying to do!!

Create  PROCEDURE usp_testing_roles @loginame varchar(50), @passwd varchar (20), @RoleName varchar(10)

exec  sp_addlogin @loginame ,@passwd

exec sp_grantdbaccess @loginame ,@name_in_db = @loginame

EXEC sp_addrole @RoleName

EXEC sp_addrolemember @RoleName , @loginame

--exec sp_addrolemember 'db_datawriter' ,@loginame

EXEC sp_grantdbaccess  @loginame

--EXEC sp_addrolemember @RoleName , @loginame


We need to run the above proc as : exec usp_testing_roles 'TestUser','asdfgt','Reader'

Now my issue iam facing is that iam not able to give permission to a ROLE. or should i said that i know how to do it but not able to understand how to do. I have some idea for that also i.e

select   'GRANT EXECUTE ON dbo.' + name + ' TO READER'
from     sysobjects
where  type  =  'U'

select   'GRANT EXECUTE ON dbo.' + name + ' TO READER'
from     sysobjects
where  type  =  'P'

Using the above code we can get all the tables list in the data(it will spit out all the code for grating permission), now if we can use that code in a cursor and grant permission to the role, i guess the work is completed.

Can you please take a look when you have sometime and help me out!

I tried running you query in SQL 2000 but it is throwing me error "'schema_name' is not a recognized function name."



Monday, September 27, 2010 - 5:34:56 PM - Gabriel Back To Top
I tried:

USE master

And it seems to have no effect. It works indivually in one database at a time 

use Database_1

(SQL 2005 sp3)

thoughts ?

Learn more about SQL Server tools