i want to ensure that all stored procedures are still syntactically valid. (This can happen if someone renames/deletes a table/column).
Right now my solution to chec
Here is an amendment which deals with multiple schemas
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[RefreshAllViews] AS
-- This sp will refresh all views in the catalog.
-- It enumerates all views, and runs sp_refreshview for each of them
DECLARE abc CURSOR FOR
SELECT TABLE_SCHEMA+'.'+TABLE_NAME AS ViewName
FROM INFORMATION_SCHEMA.VIEWS
OPEN abc
DECLARE @ViewName varchar(128)
-- Build select string
DECLARE @SQLString nvarchar(2048)
FETCH NEXT FROM abc
INTO @ViewName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQLString = 'EXECUTE sp_RefreshView ['+@ViewName+']'
PRINT @SQLString
EXECUTE sp_ExecuteSQL @SQLString
FETCH NEXT FROM abc
INTO @ViewName
END
CLOSE abc
DEALLOCATE abc
GO
I know this is a old question but this is my solution when I could not find any suiting.
I required to validate my stored procedures and views after alot of changes in the database.
Basicly what i wanted was to try to do a ALTER PROCEDURE and ALTER VIEW using the current procedures and view (not actually changing them).
I have written this that works fairly well.
Note! Do not perform on live database, make a copy to validate and then fix the things need fixing. Also sys.sql_modules can be inconsistent so take extra care. I do not use this to actually make the changes, only to check which are not working properly.
DECLARE @scripts TABLE
(
Name NVARCHAR(MAX),
Command NVARCHAR(MAX),
[Type] NVARCHAR(1)
)
DECLARE @name NVARCHAR(MAX), -- Name of procedure or view
@command NVARCHAR(MAX), -- Command or part of command stored in syscomments
@type NVARCHAR(1) -- Procedure or view
INSERT INTO @scripts(Name, Command, [Type])
SELECT P.name, M.definition, 'P' FROM sys.procedures P
JOIN sys.sql_modules M ON P.object_id = M.object_id
INSERT INTO @scripts(Name, Command, [Type])
SELECT V.name, M.definition, 'V' FROM sys.views V
JOIN sys.sql_modules M ON V.object_id = M.object_id
DECLARE curs CURSOR FOR
SELECT Name, Command, [Type] FROM @scripts
OPEN curs
FETCH NEXT FROM curs
INTO @name, @command, @type
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
IF @type = 'P'
SET @command = REPLACE(@command, 'CREATE PROCEDURE', 'ALTER PROCEDURE')
ELSE
SET @command = REPLACE(@command, 'CREATE VIEW', 'ALTER VIEW')
EXEC sp_executesql @command
PRINT @name + ' - OK'
END TRY
BEGIN CATCH
PRINT @name + ' - FAILED: ' + CAST(ERROR_NUMBER() AS NVARCHAR(MAX)) + ' ' + ERROR_MESSAGE()
--PRINT @command
END CATCH
FETCH NEXT FROM curs
INTO @name, @command, @type
END
CLOSE curs
A bit of a drawn-out option:
Couple of fussy gotchas in here, such as:
To quickly drop 10 or 1000 procedures, run
SELECT 'DROP PROCEDURE ' + schema_name(schema_id) + '.' + name
from sys.procedures
select the output, and run it.
This assumes you're doing a very infrequent task. If you have to do this regularly (daily, weekly...), please let us know why!
I know this is way old, but I created a slightly different version that actually re-creates all stored procedures, thus throwing errors if they cannot compile. This is something you do not achieve by using the SP_Recompile command.
CREATE PROCEDURE dbo.UTL_ForceSPRecompilation
(
@Verbose BIT = 0
)
AS
BEGIN
--Forces all stored procedures to recompile, thereby checking syntax validity.
DECLARE @SQL NVARCHAR(MAX)
DECLARE @SPName NVARCHAR(255)
DECLARE abc CURSOR FOR
SELECT NAME, OBJECT_DEFINITION(o.[object_id])
FROM sys.objects AS o
WHERE o.[type] = 'P'
ORDER BY o.[name]
OPEN abc
FETCH NEXT FROM abc
INTO @SPName, @SQL
WHILE @@FETCH_STATUS = 0
BEGIN
--This changes "CREATE PROCEDURE" to "ALTER PROCEDURE"
SET @SQL = 'ALTER ' + RIGHT(@SQL, LEN(@SQL) - (CHARINDEX('CREATE', @SQL) + 6))
IF @Verbose <> 0 PRINT @SPName
EXEC(@SQL)
FETCH NEXT FROM abc
INTO @SPName, @SQL
END
CLOSE abc
DEALLOCATE abc
END
In addition you might want to consider using Visual Studio Team System 2008 Database Edition which, among other things, does a static verification of all stored procedures in the project on build, thus ensuring that all are consistent with the current schema.
The check suggested by KenJ is definitely the best one, since the recreate/alter-approaches does not find all errors. E.g.
Please find my version that checks all existing SPs at once with KenJ's method below. AFAIK, it will detect every error that will keep the SP from being executed.
--Forces the creation of execution-plans for all sps.
--To achieve this, a temporary SP is created that calls all existing SPs.
--It seems like the simulation of the parameters is not necessary. That makes things a lot easier.
DECLARE @stmt NVARCHAR(MAX) = 'CREATE PROCEDURE pTempCompileTest AS ' + CHAR(13) + CHAR(10)
SELECT @stmt = @stmt + 'EXEC [' + schemas.name + '].[' + procedures.name + '];'
FROM sys.procedures
INNER JOIN sys.schemas ON schemas.schema_id = procedures.schema_id
WHERE schemas.name = 'dbo'
ORDER BY procedures.name
EXEC sp_executesql @stmt
GO
--Here, the real magic happens.
--In order to display as many errors as possible, XACT_ABORT is turned off.
--Unfortunately, for some errors, the execution stops anyway.
SET XACT_ABORT OFF
GO
--Showplan disables the actual execution, but forces t-sql to create execution-plans for every statement.
--This is the core of the whole thing!
SET SHOWPLAN_ALL ON
GO
--You cannot use dynamic SQL in here, since sp_executesql will not be executed, but only show the string passed in in the execution-plan
EXEC pTempCompileTest
GO
SET SHOWPLAN_ALL OFF
GO
SET XACT_ABORT ON
GO
--drop temp sp again
DROP PROCEDURE pTempCompileTest
--If you have any errors in the messages-window now, you should fix these...