Object reference not set to an instance of an object. (SqlMgmt) while updating extended properties with SSMS wizard - sql

While updating (Click on OK button, or Script on SSMS Wizard page),
SSMS got Error: Object reference not set to an instance of an object. (SqlMgmt)
Although there is no problem to do that action with system procedure (EXEC sys.sp_updateextendedproperty) and this will be execute successfully, but it seems that SSMS can't generate this action on wizard page (Stored Procedure Properties).
I had reinstall SSMS on my local system, but it didn't worked!
Same Error exists on every local system of our client and developer that connect to this instance! and I believe that this is a problem on instance wide of server, not SSMS on client side.
There is no Problem for update extended properties from other Object (like Tables, Views, function, etc), but just Stored Procedure!
I think maybe there is some dirty records in some System Tables on the msdb Database!!!

I solve it myself!
The Problem was that I had an Extended Property with a NULL value on all my Stored Procedures!!!
So to solve this problem should update all of them and generate the Not NULL value for them.
Below sample code will be update all the values of entire stored procedures that are exists with the NULL values in their extended properties (Just replace the YOUR_EXTENDED_PROPERTY_NAME with your own extended property name that have NULL value and should be update):
DECLARE #Query AS NVARCHAR (MAX);
DECLARE c CURSOR FOR
----------------------------------------------------
SELECT 'begin try EXEC sys.sp_updateextendedproperty #name=''YOUR_EXTENDED_PROPERTY_NAME'', #value='''' , #level0type=''SCHEMA'',#level0name='''
+ schemaName + ''', #level1type=N''PROCEDURE'',#level1name=N''' + spname + ''' End try Begin catch End catch'
FROM (
SELECT Ob.name spname,
EX.name extended_name,
sch.name AS schemaName,
EX.value
FROM sys.extended_properties AS EX
JOIN sys.objects AS Ob ON Ob.object_id = EX.major_id
JOIN sys.schemas AS sch ON sch.schema_id = Ob.schema_id
WHERE Ob.type = 'P'
AND EX.value IS NULL
) t;
----------------------------------------------------
OPEN c;
FETCH NEXT FROM c
INTO #Query;
WHILE ##fetch_status <> -1
BEGIN
EXECUTE sp_executesql #Query;
FETCH NEXT FROM c
INTO #Query;
END;
CLOSE c;
DEALLOCATE c;
Question is that, why Microsoft let to insert the NULL value and then got ERROR Object reference not set to an instance of an object. on them!!!

Related

Error during sp_refreshsqlmodule after altering table type

I am trying to add a column to a user-defined table type.
I have done some research and here is what I have now:
-- First, rename existing table type to something else
EXEC sp_rename 'TT_MY_TABLE_TYPE', 'TT_MY_TABLE_TYPE_1'
-- Create the new table type
CREATE TYPE [dbo].[TT_MY_TABLE_TYPE] AS TABLE(
[MY_FIELD] [varchar](20) NULL
)
GO
-- Do a refresh of the SP/views so that the SP/views will refer to the new table type
-- Save the list of dependencies to a temporary table
SELECT 'sp_refreshsqlmodule ' + quotename('MySchemaName.' +object_name(referencing_id), '''') AS SQL_CMD
INTO #TEMPSQL
FROM sys.sql_expression_dependencies
WHERE referenced_class_desc = 'TYPE' and referenced_entity_name = 'TT_MY_TABLE_TYPE';
DECLARE #sql NVARCHAR(1000)
-- Do a loop for the list of dependencies, use dynamic SQL to execute the SQL commands
DECLARE c_Cur CURSOR FOR
SELECT SQL_CMD
FROM #TEMPSQL
OPEN c_Cur
FETCH NEXT FROM c_Cur INTO #sql
WHILE (##FETCH_STATUS = 0)
BEGIN
EXEC SP_EXECUTESQL #statement = #sql
FETCH NEXT FROM c_Cur INTO #sql
END
CLOSE c_Cur
DEALLOCATE c_Cur
-- Drop the old table type
DROP TYPE TT_MY_TABLE_TYPE_1
DROP TABLE #TEMPSQL
Unfortunately, while refreshing stored/procedures (their dependencies) to reflect the new type I am getting the following error:
Procedure sp_refreshsqlmodule_internal, Line 85 [Batch Start Line 0]
Operand type clash: TT_MY_TABLE_TYPE is incompatible with
TT_MY_TABLE_TYPE_1.
I expect that the error is something else since all I did was adding one column to the new type.
When I try to alter the function that has this type as a dependency, I have the same Operand type clash error
Could you help me identify, what is the root cause of this problem?
To anyone, that may come across this problem:
The issue was nested dependencies.
You need to run sp_refreshsqlmodule starting from the bottom of the dependency hierarchy. If you try to refresh the Stored Procedure, that uses this table type and passes it further, you will get this operand type clash error

Drop all objects in SQL Server database that belong to different schemas?

Is there a way to drop all objects in a db, with the objects belonging to two different schemas?
I had been previously working with one schema, so I query all objects using:
Select * From sysobjects Where type=...
then dropped everything I using
Drop Table ...
Now that I have introduced another schema, every time I try to drop it says something about I don't have permission or the object does not exist. BUT, if I prefix the object with the [schema.object] it works. I don't know how to automate this, cause I don't know what objects, or which of the two schemas the object will belong to. Anyone know how to drop all objects inside a db, regardless of which schema it belongs to?
(The user used is owner of both schemas, the objects in the DB were created by said user, as well as the user who is removing the objects - which works if the prefix I used IE. Drop Table Schema1.blah)
Use sys.objects in combination with OBJECT_SCHEMA_NAME to build your DROP TABLE statements, review, then copy/paste to execute:
SELECT 'DROP TABLE ' +
QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' +
QUOTENAME(name) + ';'
FROM sys.objects
WHERE type_desc = 'USER_TABLE';
Or use sys.tables to avoid need of the type_desc filter:
SELECT 'DROP TABLE ' +
QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' +
QUOTENAME(name) + ';'
FROM sys.tables;
SQL Fiddle
Neither of the other questions seem to have tried to address the all objects part of the question.
I'm amazed you have to roll your own with this - I expected there to be a drop schema blah cascade. Surely every single person who sets up a dev server will have to do this and having to do some meta-programming before being able to do normal programming is seriously horrible. Anyway... rant over!
I started looking at some of these articles as a way to do it by clearing out a schema: There's an old article about doing this, however the tables mentioned on there are now marked as deprecated. I've also looked at the documentation for the new tables to help understand what is going on here.
There's another answer and a great dynamic sql resource it links to.
After looking at all this stuff for a while it just all seemed a bit too messy.
I think the better option is to go for
ALTER DATABASE 'blah' SET SINGLE_USER WITH ROLLBACK IMMEDIATE
drop database 'blah'
create database 'blah'
instead. The extra incantation at the top is basically to force drop the database as mentioned here
It feels a bit wrong but the amount of complexity involved in writing the drop script is a good reason to avoid it I think.
If there seem to be problems with dropping the database I might revisit some of the links and post another answer
try this with sql2012 or above,
this script may help to delete all objects by selected schema
Note: below script for dbo schema for all objects but you may change in very first line #MySchemaName
DECLARE #MySchemaName VARCHAR(50)='dbo', #sql VARCHAR(MAX)='';
DECLARE #SchemaName VARCHAR(255), #ObjectName VARCHAR(255), #ObjectType VARCHAR(255), #ObjectDesc VARCHAR(255), #Category INT;
DECLARE cur CURSOR FOR
SELECT (s.name)SchemaName, (o.name)ObjectName, (o.type)ObjectType,(o.type_desc)ObjectDesc,(so.category)Category
FROM sys.objects o
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
INNER JOIN sysobjects so ON so.name=o.name
WHERE s.name = #MySchemaName
AND so.category=0
AND o.type IN ('P','PC','U','V','FN','IF','TF','FS','FT','PK','TT')
OPEN cur
FETCH NEXT FROM cur INTO #SchemaName,#ObjectName,#ObjectType,#ObjectDesc,#Category
SET #sql='';
WHILE ##FETCH_STATUS = 0 BEGIN
IF #ObjectType IN('FN', 'IF', 'TF', 'FS', 'FT') SET #sql=#sql+'Drop Function '+#MySchemaName+'.'+#ObjectName+CHAR(13)
IF #ObjectType IN('V') SET #sql=#sql+'Drop View '+#MySchemaName+'.'+#ObjectName+CHAR(13)
IF #ObjectType IN('P') SET #sql=#sql+'Drop Procedure '+#MySchemaName+'.'+#ObjectName+CHAR(13)
IF #ObjectType IN('U') SET #sql=#sql+'Drop Table '+#MySchemaName+'.'+#ObjectName+CHAR(13)
--PRINT #ObjectName + ' | ' + #ObjectType
FETCH NEXT FROM cur INTO #SchemaName,#ObjectName,#ObjectType,#ObjectDesc,#Category
END
CLOSE cur;
DEALLOCATE cur;
SET #sql=#sql+CASE WHEN LEN(#sql)>0 THEN 'Drop Schema '+#MySchemaName+CHAR(13) ELSE '' END
PRINT #sql
EXECUTE (#sql)
I do not know wich version of Sql Server are you using, but assuming that is 2008 or later, maybe the following command will be very useful (check that you can drop ALL TABLES in one simple line):
sp_MSforeachtable "USE DATABASE_NAME DROP TABLE ?"
This script will execute DROP TABLE .... for all tables from database DATABASE_NAME. Is very simple and works perfectly. This command can be used for execute other sql instructions, for example:
sp_MSforeachtable "USE DATABASE_NAME SELECT * FROM ?"

A reliable way to verify T-SQL stored procedures

We're upgrading from SQL Server 2005 to 2008. Almost every database in the 2005 instance is set to 2000 compatibility mode, but we're jumping to 2008. Our testing is complete, but what we've learned is that we need to get faster at it.
I've discovered some stored procedures that either SELECT data from missing tables or try to ORDER BY columns that don't exist.
Wrapping the SQL to create the procedures in SET PARSEONLY ON and trapping errors in a try/catch only catches the invalid columns in the ORDER BYs. It does not find the error with the procedure selecting data from the missing table. SSMS 2008's intellisense, however, DOES find the issue, but I can still go ahead and successfully run the ALTER script for the procedure without it complaining.
So, why can I even get away with creating a procedure that fails when it runs? Are there any tools out there that can do better than what I've tried?
The first tool I found wasn't very useful: DbValidator from CodeProject, but it finds fewer problems than this script I found on SqlServerCentral, which found the invalid column references.
-------------------------------------------------------------------------
-- Check Syntax of Database Objects
-- Copyrighted work. Free to use as a tool to check your own code or in
-- any software not sold. All other uses require written permission.
-------------------------------------------------------------------------
-- Turn on ParseOnly so that we don't actually execute anything.
SET PARSEONLY ON
GO
-- Create a table to iterate through
declare #ObjectList table (ID_NUM int NOT NULL IDENTITY (1, 1), OBJ_NAME varchar(255), OBJ_TYPE char(2))
-- Get a list of most of the scriptable objects in the DB.
insert into #ObjectList (OBJ_NAME, OBJ_TYPE)
SELECT name, type
FROM sysobjects WHERE type in ('P', 'FN', 'IF', 'TF', 'TR', 'V')
order by type, name
-- Var to hold the SQL that we will be syntax checking
declare #SQLToCheckSyntaxFor varchar(max)
-- Var to hold the name of the object we are currently checking
declare #ObjectName varchar(255)
-- Var to hold the type of the object we are currently checking
declare #ObjectType char(2)
-- Var to indicate our current location in iterating through the list of objects
declare #IDNum int
-- Var to indicate the max number of objects we need to iterate through
declare #MaxIDNum int
-- Set the inital value and max value
select #IDNum = Min(ID_NUM), #MaxIDNum = Max(ID_NUM)
from #ObjectList
-- Begin iteration
while #IDNum <= #MaxIDNum
begin
-- Load per iteration values here
select #ObjectName = OBJ_NAME, #ObjectType = OBJ_TYPE
from #ObjectList
where ID_NUM = #IDNum
-- Get the text of the db Object (ie create script for the sproc)
SELECT #SQLToCheckSyntaxFor = OBJECT_DEFINITION(OBJECT_ID(#ObjectName, #ObjectType))
begin try
-- Run the create script (remember that PARSEONLY has been turned on)
EXECUTE(#SQLToCheckSyntaxFor)
end try
begin catch
-- See if the object name is the same in the script and the catalog (kind of a special error)
if (ERROR_PROCEDURE() <> #ObjectName)
begin
print 'Error in ' + #ObjectName
print ' The Name in the script is ' + ERROR_PROCEDURE()+ '. (They don''t match)'
end
-- If the error is just that this already exists then we don't want to report that.
else if (ERROR_MESSAGE() <> 'There is already an object named ''' + ERROR_PROCEDURE() + ''' in the database.')
begin
-- Report the error that we got.
print 'Error in ' + ERROR_PROCEDURE()
print ' ERROR TEXT: ' + ERROR_MESSAGE()
end
end catch
-- Setup to iterate to the next item in the table
select #IDNum = case
when Min(ID_NUM) is NULL then #IDNum + 1
else Min(ID_NUM)
end
from #ObjectList
where ID_NUM > #IDNum
end
-- Turn the ParseOnly back off.
SET PARSEONLY OFF
GO
You can choose different ways. First of all SQL SERVER 2008 supports dependencies which exist in DB inclusive dependencies of STORED PROCEDURE (see http://msdn.microsoft.com/en-us/library/bb677214%28v=SQL.100%29.aspx, http://msdn.microsoft.com/en-us/library/ms345449.aspx and http://msdn.microsoft.com/en-us/library/cc879246.aspx). You can use sys.sql_expression_dependencies and sys.dm_sql_referenced_entities to see and verify there.
But the most simple way to do verification of all STORED PROCEDURE is following:
export all STORED PROCEDURE
drop old existing STORED PROCEDURE
import just exported STORED PROCEDURE.
If you upgrade DB the existing Stored Procedure will be not verified, but if you create a new one, the procedure will be verified. So after exporting and exporting of all Stored Procedure you receive all existing error reported.
You can also see and export the code of a Stored Procedure with a code like following
SELECT definition
FROM sys.sql_modules
WHERE object_id = (OBJECT_ID(N'spMyStoredProcedure'))
UPDATED: To see objects (like tables and views) referenced by Stored Procedure spMyStoredProcedure you can use following:
SELECT OBJECT_NAME(referencing_id) AS referencing_entity_name
,referenced_server_name AS server_name
,referenced_database_name AS database_name
,referenced_schema_name AS schema_name
, referenced_entity_name
FROM sys.sql_expression_dependencies
WHERE referencing_id = OBJECT_ID(N'spMyStoredProcedure');
UPDATED 2: In the comment to my answer Martin Smith suggested to use sys.sp_refreshsqlmodule instead of recreating a Stored Procedure. So with the code
SELECT 'EXEC sys.sp_refreshsqlmodule ''' + OBJECT_SCHEMA_NAME(object_id) +
'.' + name + '''' FROM sys.objects WHERE type in (N'P', N'PC')
one receive a script, which can be used for verifying of Stored Procedure dependencies. The output will look like following (example with AdventureWorks2008):
EXEC sys.sp_refreshsqlmodule 'dbo.uspGetManagerEmployees'
EXEC sys.sp_refreshsqlmodule 'dbo.uspGetWhereUsedProductID'
EXEC sys.sp_refreshsqlmodule 'dbo.uspPrintError'
EXEC sys.sp_refreshsqlmodule 'HumanResources.uspUpdateEmployeeHireInfo'
EXEC sys.sp_refreshsqlmodule 'dbo.uspLogError'
EXEC sys.sp_refreshsqlmodule 'HumanResources.uspUpdateEmployeeLogin'
EXEC sys.sp_refreshsqlmodule 'HumanResources.uspUpdateEmployeePersonalInfo'
EXEC sys.sp_refreshsqlmodule 'dbo.uspSearchCandidateResumes'
EXEC sys.sp_refreshsqlmodule 'dbo.uspGetBillOfMaterials'
EXEC sys.sp_refreshsqlmodule 'dbo.uspGetEmployeeManagers'
Here is what worked for me:
-- Based on comment from http://blogs.msdn.com/b/askjay/archive/2012/07/22/finding-missing-dependencies.aspx
-- Check also http://technet.microsoft.com/en-us/library/bb677315(v=sql.110).aspx
select o.type, o.name, ed.referenced_entity_name, ed.is_caller_dependent
from sys.sql_expression_dependencies ed
join sys.objects o on ed.referencing_id = o.object_id
where ed.referenced_id is null
You should get all missing dependencies for your SPs, solving problems with late binding.
Exception: is_caller_dependent = 1 does not necessarily mean a broken dependency. It just means that the dependency is resolved on runtime because the schema of the referenced object is not specified. You can avoid it specifying the schema of the referenced object (another SP for example).
Credits to Jay's blog and the anonymous commenter...
I am fond of using Display Estimated Execution Plan. It highlights many errors reasonably without ever having to really run the proc.
I had the same problem in a previous project and wrote an TSQL checker on SQL2005 and later a Windows program implementing the same functionality.
When I came across this question I was interested in finding a safe, non-invasive, and fast technique for validating syntax and object (table, column) references.
While I agree that actually executing each stored procedure will likely turn up more issues than just compiling them, one must exercise caution with the former approach. That is, you need to know that it is, in fact, safe to execute each and every stored procedure (i.e. does it erase some tables, for example?). This safety issue can be addressed by wrapping the execution in a transaction and rolling it back so no changes are permanent, as suggested in devio's answer. Still, this approach could potentially take quite a long time depending on how much data you are manipulating.
The code in the question, and the first portion of Oleg's answer, both suggest re-instantiating each stored procedure, as that action recompiles the procedure and does just such syntactic validation. But this approach is invasive--it's fine for a private test system, but could disrupt the work of other develoeprs on a heavily used test system.
I came across the article Check Validity of SQL Server Stored Procedures, Views and Functions, which presents a .NET solution, but it is the follow-up post at the bottom by "ddblue" that intrigued me more. This approach obtains the text of each stored procedure, converts the create keyword to alter so that it can be compiled, then compiles the proc. And that accurately reports any bad table and column references. The code runs, but I quickly ran into some issues because of the create/alter conversion step.
The conversion from "create" to "alter" looks for "CREATE" and "PROC" separated by a single space. In the real-world, there could spaces or tabs, and there could be one or more than one. I added a nested "replace" sequence (thanks, to this article by Jeff Moden!) to convert all such occurrences to a single space, allowing the conversion to proceed as originally designed. Then, since that needed to be used wherever the original "sm.definition" expression was used, I added a common table expression to avoid massive, unsightly code duplication. So here is my updated version of the code:
DECLARE #Schema NVARCHAR(100),
#Name NVARCHAR(100),
#Type NVARCHAR(100),
#Definition NVARCHAR(MAX),
#CheckSQL NVARCHAR(MAX)
DECLARE crRoutines CURSOR FOR
WITH System_CTE ( schema_name, object_name, type_desc, type, definition, orig_definition)
AS -- Define the CTE query.
( SELECT OBJECT_SCHEMA_NAME(sm.object_id) ,
OBJECT_NAME(sm.object_id) ,
o.type_desc ,
o.type,
REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(REPLACE(sm.definition, char(9), ' '))), ' ', ' ' + CHAR(7)), CHAR(7) + ' ', ''), CHAR(7), '') [definition],
sm.definition [orig_definition]
FROM sys.sql_modules (NOLOCK) AS sm
JOIN sys.objects (NOLOCK) AS o ON sm.object_id = o.object_id
-- add a WHERE clause here as indicated if you want to test on a subset before running the whole list.
--WHERE OBJECT_NAME(sm.object_id) LIKE 'xyz%'
)
-- Define the outer query referencing the CTE name.
SELECT schema_name ,
object_name ,
type_desc ,
CASE WHEN type_desc = 'SQL_STORED_PROCEDURE'
THEN STUFF(definition, CHARINDEX('CREATE PROC', definition), 11, 'ALTER PROC')
WHEN type_desc LIKE '%FUNCTION%'
THEN STUFF(definition, CHARINDEX('CREATE FUNC', definition), 11, 'ALTER FUNC')
WHEN type = 'VIEW'
THEN STUFF(definition, CHARINDEX('CREATE VIEW', definition), 11, 'ALTER VIEW')
WHEN type = 'SQL_TRIGGER'
THEN STUFF(definition, CHARINDEX('CREATE TRIG', definition), 11, 'ALTER TRIG')
END
FROM System_CTE
ORDER BY 1 , 2;
OPEN crRoutines
FETCH NEXT FROM crRoutines INTO #Schema, #Name, #Type, #Definition
WHILE ##FETCH_STATUS = 0
BEGIN
IF LEN(#Definition) > 0
BEGIN
-- Uncomment to see every object checked.
-- RAISERROR ('Checking %s...', 0, 1, #Name) WITH NOWAIT
BEGIN TRY
SET PARSEONLY ON ;
EXEC ( #Definition ) ;
SET PARSEONLY OFF ;
END TRY
BEGIN CATCH
PRINT #Type + ': ' + #Schema + '.' + #Name
PRINT ERROR_MESSAGE()
END CATCH
END
ELSE
BEGIN
RAISERROR ('Skipping %s...', 0, 1, #Name) WITH NOWAIT
END
FETCH NEXT FROM crRoutines INTO #Schema, #Name, #Type, #Definition
END
CLOSE crRoutines
DEALLOCATE crRoutines
Nine years after I first posed this question, and I've just discovered an amazing tool built by Microsoft themselves that not only can reliably verify stored procedure compatibility between SQL Server versions, but all other internal aspects as well. It's been renamed a few times, but they currently call it:
Microsoft® Data Migration Assistant v5.4*
* Version as of 6/17/2021
https://www.microsoft.com/en-us/download/details.aspx?id=53595
Data Migration Assistant (DMA) enables you to upgrade to a modern data platform by detecting compatibility issues that can impact database functionality on your new version of SQL Server. It recommends performance and reliability improvements for your target environment. It allows you to not only move your schema and data, but also uncontained objects from your source server to your target server.
The answers above that use EXEC sys.sp_refreshsqlmodule were a great start, but we ran into one MAJOR problem running it on 2008 R2: any stored procedure or function that was renamed (using sp_rename, and not a DROP/CREATE pattern) REVERTED to its prior definition after running the refresh procedure, because the internal metadata isn't refreshed under the new name. It's a known bug that was fixed in SQL Server 2012, but we had a fun day of recovery afterwards. (One workaround, future readers, is to issue a ROLLBACK if the refresh throws an error.)
Anyway, times have changed, new tools are available -- and good ones at that -- thus the late addition of this answer.

How do I programatically perform a Modify on all stored procedures in my database in SQL 2008

What I want to do is simulate right clicking a stored procedure an selecting Modify, then execute so that my stored procedure runs.
Some of the tables in our database have changed and not all the sp's have been modified.
ie old SP =
ALTER PROCEDURE [dbo].[myProcedure]
SELECT name, address, typename from names
GO
Then the names table was modified and the typename column removed.
If i click modify on the SP then execute I get an error message in the messages output window.
I would like to do this for every sp in my database so i can see that it runs without errors.
(we have 200 sps and it would take a long time to do it manually)
Any ideas would be much appreciated.
You should compose a text file of test cases in the form:
exec <stored proc> [args]
if (##error <> 0)
begin
print "Fail"
end
go
Unfortunately there is no way to automate this further unless either:
None of your stored procedures take parameters.
Your stored procedure parameters are derivable (highly unlikely).
Even if you do supply one particular set of parameter values, this isn't comprehensively testing that all stored procs in your database are bug free. It just verifies that the sproc runs for those particular arguments. The bottom line: There are no short-cuts when it comes to proper unit testing.
You could write a cursor to run through each of them execution them. But how would you know what values to provide for the input parameters? If none of them have parameters something like this will work.
DECLARE #proc sysname
DECLARE cur CURSOR FOR SELECT '[' + schema_name(schema_id) + '].[' + name + ']'
FROM sys.procedures
OPEN cur
FETCH NEXT FROM cur INTO #proc
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC (#proc)
FETCH NEXT FROM cur INTO #proc
END
CLOSE cur
DEALLOCATE cur
Handling parameters (assuming you can figure out the values to use) would be along the same lines with an inner loop to get the parameter names, then supply them with values.

sql 2005 force table rename that has dependencies

How do you force a rename???
Rename failed for Table 'dbo.x. (Microsoft.SqlServer.Smo)
For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.0.2531.0+((Katmai_PCU_Main).090329-1045+)&EvtSrc=Microsoft.SqlServer.Management.Smo.ExceptionTemplates.FailedOperationExceptionText&EvtID=Rename+Table&LinkId=20476
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
Object '[dbo].[x]' cannot be renamed because the object participates in enforced dependencies. (Microsoft SQL Server, Error: 15336)
For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=09.00.4035&EvtSrc=MSSQLServer&EvtID=15336&LinkId=20476
Find the "enforced dependencies", then remove or disable them.
By "enforced dependencies", it means Schema binding, so you'll have to look specifically for that.
Here's a query to look for schema binding references to your object:
select o.name as ObjName, r.name as ReferencedObj
from sys.sql_dependencies d
join sys.objects o on o.object_id=d.object_id
join sys.objects r on r.object_id=d.referenced_major_id
where d.class=1
AND r.name = #YourObjectName
As I noted in the comments, there is no way to FORCE-ibly override Schema Binding. When you use Schema Binding, you are explicitly saying "Do not let me or anyone else override this." The only way around Schema Binding is to undo it, and that's intentional.
I had the same issue , my problem was that i has a COMPUTED FIELD using the column i was trying to rename.
by running the query from the selected answer i was able to tell that had enforced dependencies, but i was not able to see exactly what was the problem
Try this:
/*
Example 1: Rename a table dbo.MyTable -> dbo.YourTable
EXEC dbo.USP_DROP_ENFORCED_DEPENDENCIES #SchemaName=N'dbo', #EntityName=N'MyTable', #Debug=1;
EXEC sp_rename N'dbo.MyTable', N'YourTable', N'OBJECT'
Example 2: Rename a column dbo.MyTable.MyColumn -> dbo.MyTable.YourColumn
EXEC dbo.USP_DROP_ENFORCED_DEPENDENCIES #SchemaName=N'dbo', #EntityName=N'MyTable', #ColumnName=N'MyColumn' #Debug=1;
EXEC sp_rename N'dbo.MyTable.MyColumn', N'YourColumn', N'COLUMN'
*/
CREATE Procedure dbo.USP_DROP_ENFORCED_DEPENDENCIES
(
#SchemaName sysname = 'dbo',
#EntityName sysname,
#ColumnName sysname = NULL,
#Debug bit = 0
)
AS
BEGIN
SET NOCOUNT ON;
SET ROWCOUNT 0;
DECLARE #ReferencingEntitySchema sysname, #ReferencingEntityName sysname, #ReferencingEntityType nvarchar(8), #SqlScript nvarchar(512);
DECLARE ReferencingEntitiesCursor CURSOR LOCAL FORWARD_ONLY
FOR
SELECT OBJECT_SCHEMA_NAME(dep.referencing_id) AS [schema]
,referencing_entity.name
,CASE referencing_entity.type
WHEN 'V' THEN N'VIEW'
ELSE /*IF, FN, TF*/ N'FUNCTION'
END as [type]
FROM sys.sql_expression_dependencies AS dep
INNER JOIN sys.objects AS referencing_entity
ON dep.referencing_id = referencing_entity.object_id
WHERE dep.referenced_entity_name = #EntityName
AND dep.referenced_schema_name = #SchemaName
AND is_schema_bound_reference = 1
AND ((#ColumnName IS NULL AND dep.referenced_minor_id = 0) OR COL_NAME(dep.referenced_id, dep.referenced_minor_id) = #ColumnName)
OPEN ReferencingEntitiesCursor
FETCH NEXT FROM ReferencingEntitiesCursor
INTO #ReferencingEntitySchema, #ReferencingEntityName, #ReferencingEntityType;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC dbo.USP_DROP_ENFORCED_DEPENDENCIES #SchemaName=#ReferencingEntitySchema, #EntityName=#ReferencingEntityName, #Debug=#Debug;
--The goal is to produce the following script:
/*
DROP FUNCTION dbo.UFN_SOME_FUNCTION;
OR
DROP VIEW dbo.UFN_SOME_VIEW;
*/
SET #SqlScript = N'DROP ' + #ReferencingEntityType + N' ' + #ReferencingEntitySchema + '.' + #ReferencingEntityName;
IF(#Debug = 1)
RAISERROR (#SqlScript, 0/*severity*/, 0/*state*/) WITH NOWAIT;
EXEC (#SqlScript);
FETCH NEXT FROM ReferencingEntitiesCursor
INTO #ReferencingEntitySchema, #ReferencingEntityName, #ReferencingEntityType;
END
CLOSE ReferencingEntitiesCursor;
DEALLOCATE ReferencingEntitiesCursor;
END
GO
In the SQL Server Object Browser, right-click on the table with the issue and select View Dependencies. Next in the view listed, Right-click (view) and select SCRIPT to CREATE VIEW in New SQL Query Editor window, then remove WITH SCHEMABINDING from the CREATE VIEW t-sql script and run the revised CREATE VIEW t-sql. This unlinks the schema dependency from the table. I was able to recreate the table at this point (DROP, RENAME, etc).
Note:
Schema binding can occur on functions and other objects in your db.
Use of View Dependencies on the object throwing the error is essential
to fix the issue.
BTW:
I originally added schema binding to enable view indexing. Keeping a
good index on the underlying table(s) may mitigate the performance hit
of not having one on the view.
View Dependencies
More on Schema Binding
I had an issue like this. I dropped constraints on this DB object, renamed the DB object then recreated these constraints. This solved my problem.
I used this script to get dependent view with schemabingings:
select distinct o.name, o.type from sys.sql_expression_dependencies dep inner join sys.objects o on dep.referencing_id=o.object_id where referenced_id = OBJECT_ID(<your dependency owner object>) and o.type = 'V'