Comment vérifier toutes les procédures stockées est ok dans le serveur SQL si je dépose une table ou des champs?Comment faire pour vérifier toutes les procédures stockées est ok dans le serveur SQL?
Répondre
Couple de moyens qui viennent à l'esprit
- La façon la plus évidente exécuter les procédures
- des dépendances de contrôle sur la table avant de déposer la table ou un champ. puis vérifier les proceudres dépendants
- générer des scripts sur toutes les procédures et la recherche de ce champ ou une table
- Recherche sysobjects
Il ne sera pas attraper tout (SQL dynamique ou objets latebound), mais il peut être utile - appeler sp_refreshsqlmodule sur tous les non-schéma lié des procédures stockées (vous pouvez l'appeler avant de faire en sorte que les dépendances sont mises à jour et interroger les dépendances, ou l'appeler par la suite et voir si quelque chose est cassé):
DECLARE @template AS varchar(max)
SET @template = 'PRINT ''{OBJECT_NAME}''
EXEC sp_refreshsqlmodule ''{OBJECT_NAME}''
'
DECLARE @sql AS varchar(max)
SELECT @sql = ISNULL(@sql, '') + REPLACE(@template, '{OBJECT_NAME}',
QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME))
FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
EXEC (
@sql
)
I trouvé Cade nous répondre eful dans la formulation de mon propre script pour le contrôle des objets dans une base de données, donc je pensais que je partagerais mon script ainsi:
DECLARE @Name nvarchar(1000);
DECLARE @Sql nvarchar(1000);
DECLARE @Result int;
DECLARE ObjectCursor CURSOR FAST_FORWARD FOR
SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(OBJECT_NAME(o.object_id))
FROM sys.objects o
WHERE type_desc IN (
'SQL_STORED_PROCEDURE',
'SQL_TRIGGER',
'SQL_SCALAR_FUNCTION',
'SQL_TABLE_VALUED_FUNCTION',
'SQL_INLINE_TABLE_VALUED_FUNCTION',
'VIEW')
--include the following if you have schema bound objects since they are not supported
AND ISNULL(OBJECTPROPERTY(o.object_id, 'IsSchemaBound'), 0) = 0
;
OPEN ObjectCursor;
FETCH NEXT FROM ObjectCursor INTO @Name;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Sql = N'EXEC sp_refreshsqlmodule ''' + @Name + '''';
--PRINT @Sql;
BEGIN TRY
EXEC @Result = sp_executesql @Sql;
IF @Result <> 0 RAISERROR('Failed', 16, 1);
END TRY
BEGIN CATCH
PRINT 'The module ''' + @Name + ''' does not compile.';
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
END CATCH
FETCH NEXT FROM ObjectCursor INTO @Name;
END
CLOSE ObjectCursor;
DEALLOCATE ObjectCursor;
La seule façon d'actualiser les déclencheurs est de les modifier s'ils ne sont pas cryptés. (http://connect.microsoft.com/SQLServer/feedback/details/261905/sp-refreshsqlmodule-does-not-work-with-triggers). Donc le script ci-dessus donne des faux positifs quand il rencontre un trigger – buckley
Cela a très bien fonctionné pour moi. (bien que je n'ai aucun déclencheur) – ClearCloud8
Nice post, fonctionne parfaitement! Une addition de plus, vous devez vérifier si l'objet est lié au schéma car sp_refreshsqlmodule donnera de faux négatifs car les objets liés au schéma ne sont pas supportés. Donc, ajoutez à votre requête ce qui suit: et \t isnull (objectproperty (o.object_id, 'IsSchemaBound'), 0) = 0 \t; –
Outre le script de Michael Petito vous pouvez vérifier les problèmes avec des objets tardifs liés dans SPs (résolution de nom différé) comme ceci:
-- 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
Le problème est qu'il retournera toujours les alias CTE et les tables temporaires en tant que références nulles. –
J'ai essayé « Cade Roux » réponse, il a mal tourné et je l'ai fixé comme suit
SELECT 'BEGIN TRAN T1;' UNION
SELECT REPLACE('BEGIN TRY
EXEC sp_refreshsqlmodule ''{OBJECT_NAME}''
END TRY
BEGIN CATCH
PRINT ''{OBJECT_NAME} IS INVALID.''
END CATCH', '{OBJECT_NAME}',
QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME))
FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
UNION
SELECT 'ROLLBACK TRAN T1;'
Veuillez mettre en forme le code. – rajuGT
Je suis essentiellement fait la même chose, mais écrit à être CURSORless qui est super rapide.
DECLARE @Name nvarchar(1000);
DECLARE @Sql nvarchar(1000);
DECLARE @Result int;
DECLARE @Objects TABLE (
Id INT IDENTITY(1,1),
Name nvarchar(1000)
)
INSERT INTO @Objects
SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(OBJECT_NAME(o.object_id))
FROM sys.objects o
WHERE type_desc IN (
'SQL_STORED_PROCEDURE',
'SQL_TRIGGER',
'SQL_SCALAR_FUNCTION',
'SQL_TABLE_VALUED_FUNCTION',
'SQL_INLINE_TABLE_VALUED_FUNCTION',
'VIEW')
--include the following if you have schema bound objects since they are not supported
AND ISNULL(OBJECTPROPERTY(o.object_id, 'IsSchemaBound'), 0) = 0
DECLARE @x INT
DECLARE @xMax INT
SELECT @xMax = MAX(Id) FROM @Objects
SET @x = 1
WHILE @x < @xMax
BEGIN
SELECT @Name = Name FROM @Objects WHERE Id = @x
SET @Sql = N'EXEC sp_refreshsqlmodule ''' + @Name + '''';
--PRINT @Sql;
BEGIN TRY
EXEC @Result = sp_executesql @Sql;
IF @Result <> 0 RAISERROR('Failed', 16, 1);
END TRY
BEGIN CATCH
PRINT 'The module ''' + @Name + ''' does not compile.';
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
END CATCH
SET @x = @x + 1
END
L'utilisation d'une instruction while pour faire défiler une table de données est fondamentalement la même chose que d'utiliser un curseur avec fast_forward. Les deux vont en ligne par rangée agonisante (RBAR). C'est une situation où elle est acceptable puisqu'elle ne peut pas être remplacée par une opération basée sur un ensemble. – Nicholas
Les curseurs ne sont pas très performants. Ce sont des porcs de la mémoire. –
Cela fonctionne un peu mieux que d'utiliser le curseur, même s'il utilise encore une boucle while. –
Il semble sp_refreshsqlmodule [peut finir rafraîchissant mais le mauvais module!] (Https://connect.microsoft.com/SQLServer/feedback/details/656863/sp-refreshsqlmodule-corrupts-renamed-objects-definitions –
@Martin Oui, j'aurais dû le mentionner. Dans mon cas, parce que c'était un ALTER et qu'il n'y avait pas une autre procédure utilisant le même nom, j'ai eu une erreur, ça n'a rien fait de mal. –