Existe-t-il un outil qui trouvera tous les objets dans SQL Server (fonctions, procs, vues) qui ne peuvent pas fonctionner car ils font référence à des objets qui n'existent pas?Trouver des objets brisés dans SQL Server
Répondre
J'utilise en fait la procédure sys.refreshmodule maintenant enveloppé dans un script Powershell avec SQL Server Powershell COLMATAGES.
Cela fonctionne mieux parce que cette petite fonction pratique sys se débarrasse de la substance CREATE vs ALTER. D'autres réponses utilisent également cette approche, mais je préfère celle qui est enveloppée dans Powershell et peut-être que certains la trouveront utile.
$server = "YourDBServer"
cls
Import-Module “sqlps” -DisableNameChecking
$databases = Invoke-Sqlcmd -Query "select name from sys.databases where name not in ('master', 'tempdb', 'model', 'msdb')" -ServerInstance $server
foreach ($db in $databases) {
$dbName = $db.name
$procedures = Invoke-Sqlcmd -Query "select SCHEMA_NAME(schema_id) as [schema], name from $dbName.sys.procedures" -ServerInstance $server
foreach ($proc in $procedures) {
if ($schema) {
$shortName = $proc.schema + "." + $proc.name
$procName = $db.name + "." + $shortName
try {
$result = Invoke-Sqlcmd -Database $dbName -Query "sys.sp_refreshsqlmodule '$shortName'" -ServerInstance $server -ErrorAction Stop
Write-Host "SUCCESS|$procName"
}
catch {
$msg = $_.Exception.Message.Replace([Environment]::NewLine, ",")
Write-Host "FAILED|$procName|$msg" -ForegroundColor Yellow
}
}
}
}
Vous pouvez être intéressé à vérifier les articles suivants:
Vous pouvez tester la solution de Michael J. Swart comme suit:
CREATE PROCEDURE proc_bad AS
SELECT col FROM nonexisting_table
GO
SELECT
OBJECT_NAME(referencing_id) AS [this sproc or VIEW...],
referenced_entity_name AS [... depends ON this missing entity name]
FROM
sys.sql_expression_dependencies
WHERE
is_ambiguous = 0
AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY
OBJECT_NAME(referencing_id), referenced_entity_name;
Quels retours:
+------------------------+------------------------------------------+
| this sproc or VIEW... | ... depends ON this missing entity name |
|------------------------+------------------------------------------|
| proc_bad | nonexisting_table |
+------------------------+------------------------------------------+
Cela semble vraiment prometteur. Il y a un léger défaut dans la clause where. Il a besoin de "AND ISNULL (sys.sql_expression_dependencies.reference_database_name, 'XXX') = 'XXX' "si vous utilisez des requêtes inter-base de données –
J'approuve cette solution :-) Gardez à l'esprit qu'elle repose sur sys.sql_expression_dependencies qui est une nouvelle vue dans SQL Server 2008. –
un * lot * de faux positifs sur mes bases de test - peut-être des entités dans plusieurs schémas, pourrait être l'utilisation de synonymes.L'autre script dans une réponse ici et le script dans le commentaire # 5 du lien Michael J Swart produisent tous deux des résultats qui ressemblent mieux mais pas tout à fait d'accord - va passer en revue les résultats et trouver pourquoi, et qui peut être approuvé! – eftpotrm
Votre meilleur pari est de commencer à utiliser un outil comme Visual Studio Database Edition. Son rôle est de gérer un schéma de base de données. Une des choses qu'il va faire est de lancer une erreur quand vous essayez de construire le projet de base de données et qu'il contient des objets cassés. Il va bien sûr faire beaucoup plus que cela. L'outil est gratuit pour tout utilisateur de Visual Studio Team Suite ou de Visual Studio Developer Edition.
Hélas cela ne fonctionnera pas Ce produit ne gère pas les références circulaires entre les bases de données –
La fonctionnalité SQL Prompt 5 de Red Gate Software comporte une fonctionnalité Find Invalid Objects qui peut s'avérer utile dans cette situation. L'outil parcourt la base de données pour trouver des objets qui donneront une erreur lors de l'exécution, ce qui sonne exactement ce que vous voulez.
Vous pouvez télécharger gratuitement un essai gratuit de 14 jours. Vous pouvez donc essayer et voir si cela vous aide.
Paul Stephenson
Chef de projet SQL Prompt
Red Gate Software
An [commentaires d'utilisateurs anonymes] (http://stackoverflow.com/suggested-edits/202231) que votre outil ne fonctionne pas correctement lorsqu'une fonction est manquante (ce qui serait mieux pour vous un rapport de bogue?) – Rup
Notez la requête dans ce thread trouve des objets manquants, et non pas ceux non valides.
SQL Server ne trouve pas qu'un objet référençant n'est pas valide tant que vous ne l'avez pas exécuté.
Amélioration de cette requête pour manipuler des objets dans d'autres schémas ainsi que les types:
SELECT
'[' + OBJECT_SCHEMA_NAME(referencing_id) + '].[' + OBJECT_NAME(referencing_id) + ']'
AS [this sproc, UDF or VIEW...],
isnull('[' + referenced_schema_name + '].', '') + '[' + referenced_entity_name + ']'
AS [... depends ON this missing entity name]
FROM
sys.sql_expression_dependencies
WHERE
is_ambiguous = 0 AND
(
(
[referenced_class_desc] = 'TYPE' and
TYPE_ID(
isnull('[' + referenced_schema_name + '].', '') +
'[' + referenced_entity_name + ']'
) IS NULL
) or
(
[referenced_class_desc] <> 'TYPE' and
OBJECT_ID(
isnull('[' + referenced_schema_name + '].', '') +
'[' + referenced_entity_name + ']'
) IS NULL
)
)
ORDER BY
'[' + OBJECT_SCHEMA_NAME(referencing_id) + '].[' + OBJECT_NAME(referencing_id) + ']',
isnull('[' + referenced_schema_name + '].', '') + '[' + referenced_entity_name + ']'
Ceci est produisant un faux positif pour moi quand vous avez une référence de croix-DB, désolé. – eftpotrm
Les deux solutions précédentes sont intéressantes ici, mais les deux échoué sur mes bases de données de test.
Le script Michael J Swart original a produit un grand nombre de faux positifs pour moi, beaucoup trop à parcourir. La solution de Rick V. était meilleure ici - les seuls faux positifs qu'elle a donnés étaient pour les références de bases de données croisées.
Il ya un commentaire sur l'article de Michael J Swart par RaduSun qui donne une solution que je ne peux pas encore casser si! Ceci est, légèrement modifié pour la lisibilité et mes objectifs, mais le crédit à RaduSun pour la logique.
SELECT
QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.'
+ QuoteName(OBJECT_NAME(referencing_id)) AS ProblemObject,
o.type_desc,
ISNULL(QuoteName(referenced_server_name) + '.', '')
+ ISNULL(QuoteName(referenced_database_name) + '.', '')
+ ISNULL(QuoteName(referenced_schema_name) + '.', '')
+ QuoteName(referenced_entity_name) AS MissingReferencedObject
FROM
sys.sql_expression_dependencies sed
LEFT JOIN sys.objects o
ON sed.referencing_id=o.object_id
WHERE
(is_ambiguous = 0)
AND (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '')
+ ISNULL(QuoteName(referenced_database_name) + '.', '')
+ ISNULL(QuoteName(referenced_schema_name) + '.', '')
+ QuoteName(referenced_entity_name)) IS NULL)
ORDER BY
ProblemObject,
MissingReferencedObject
C'est génial, sauf qu'il ne gère pas les références aux types définis par l'utilisateur. Pour une solution rapide et sale pour moi-même, je viens d'ajouter 'AND NOT EXISTS (SELECT * FROM sys.types WHERE types.nom = nom_réité_référé ET types.schema_id = ISNULL (SCHEMA_ID (nom_schéma_référencé), SCHEMA_ID ('dbo'))) 'à la clause' WHERE', mais il y a probablement un meilleur moyen. – siride
Merci siride pour l'étendre à gérer cela, je n'ai eu aucun UDT pour le tester contre :-) – eftpotrm
J'ai utilisé cette requête pendant un certain temps jusqu'à ce que nous avons mis à niveau vers SQL 2016. Maintenant, il signale chaque déclencheur comme non valide en raison de références aux tables INSERTED et DELETED –
/*
modified version of script from http://michaeljswart.com/2009/12/find-missing-sql-dependencies/
Added columns for object types & generated refresh module command...
filter out user-define types: http://stackoverflow.com/questions/2330521/find-broken-objects-in-sql-server
*/
SELECT TOP (100) PERCENT
QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) AS [this Object...],
o.type_desc,
ISNULL(QuoteName(referenced_server_name) + '.', '')
+ ISNULL(QuoteName(referenced_database_name) + '.', '')
+ ISNULL(QuoteName(referenced_schema_name) + '.', '')
+ QuoteName(referenced_entity_name) AS [... depends ON this missing entity name]
,sed.referenced_class_desc
,case when o.type_desc in('SQL_STORED_PROCEDURE' ,'SQL_SCALAR_FUNCTION' ,'SQL_TRIGGER' ,'VIEW')
then 'EXEC sys.sp_refreshsqlmodule ''' + QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) + ''';'
else null
end as [Refresh SQL Module command]
FROM sys.sql_expression_dependencies as sed
LEFT JOIN sys.objects o
ON sed.referencing_id=o.object_id
WHERE (is_ambiguous = 0)
AND (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '')
+ ISNULL(QuoteName(referenced_database_name) + '.', '')
+ ISNULL(QuoteName(referenced_schema_name) + '.', '')
+ QuoteName(referenced_entity_name)) IS NULL)
AND NOT EXISTS
(SELECT *
FROM sys.types
WHERE types.name = referenced_entity_name
AND types.schema_id = ISNULL(SCHEMA_ID(referenced_schema_name), SCHEMA_ID('dbo'))
)
ORDER BY [this Object...],
[... depends ON this missing entity name]
First query
vous donnera le nom d'objets cassés comprendStored Procedure
,View
,Scalar function
,DML trigger
,Table-valued-function
Type
/*
/////////////
////ERROR////
/////////////
All error will be listed if object is broken
*/
DECLARE @AllObjectName TABLE (
OrdinalNo INT IDENTITY
,ObjectName NVARCHAR(MAX)
,ObjectType NVARCHAR(MAX)
,ErrorMessage NVARCHAR(MAX)
)
INSERT INTO @AllObjectName (
ObjectName
,ObjectType
)
SELECT '[' + SCHEMA_NAME(schema_id) + '].[' + NAME + ']' ObjectName
,CASE [TYPE]
WHEN 'P'
THEN 'Stored Procedure'
WHEN 'V'
THEN 'View'
WHEN 'FN'
THEN 'Scalar function'
WHEN 'TR'
THEN 'DML trigger'
WHEN 'TF'
THEN 'Table-valued-function'
ELSE 'Unknown Type'
END
FROM sys.objects
WHERE [TYPE] IN (
'P'
,'V'
,'FN'
,'TR'
,'TF'
)
ORDER BY NAME
DECLARE @i INT = 1
DECLARE @RowCount INT = (
SELECT count(1)
FROM @AllObjectName
)
DECLARE @ObjectName VARCHAR(MAX)
WHILE @i <= @RowCount
BEGIN
BEGIN TRY
SET @ObjectName = (
SELECT ObjectName
FROM @AllObjectName
WHERE OrdinalNo = @i
)
EXEC sys.sp_refreshsqlmodule @ObjectName
END TRY
BEGIN CATCH
DECLARE @message VARCHAR(4000)
,@xstate INT;
SELECT @message = ERROR_MESSAGE()
,@xstate = XACT_STATE();
IF @xstate = - 1
ROLLBACK;
UPDATE @AllObjectName
SET ErrorMessage = @message
WHERE OrdinalNo = @i
END CATCH
SET @i = @i + 1
END
SELECT ObjectName
,ObjectType
,ErrorMessage
FROM @AllObjectName
WHERE ErrorMessage IS NOT NULL
Et la
below one
recherche de références non résolues .. En général, qui a traité commewarning
, est peut-être encore quelque temps causererror
/*
/////////////
///Warning///
/////////////
Here all warning will come if object reference is not stated properly
*/
SELECT TOP (100) PERCENT QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) AS [this Object...]
,o.type_desc
,ISNULL(QuoteName(referenced_server_name) + '.', '') + ISNULL(QuoteName(referenced_database_name) + '.', '') + ISNULL(QuoteName(referenced_schema_name) + '.', '') + QuoteName(referenced_entity_name) AS [... depends ON this missing entity name]
,sed.referenced_class_desc
FROM sys.sql_expression_dependencies AS sed
LEFT JOIN sys.objects o ON sed.referencing_id = o.object_id
WHERE (is_ambiguous = 0)
AND (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '') + ISNULL(QuoteName(referenced_database_name) + '.', '') + ISNULL(QuoteName(referenced_schema_name) + '.', '') + QuoteName(referenced_entity_name)) IS NULL)
AND NOT EXISTS (
SELECT *
FROM sys.types
WHERE types.NAME = referenced_entity_name
AND types.schema_id = ISNULL(SCHEMA_ID(referenced_schema_name), SCHEMA_ID('dbo'))
)
ORDER BY [this Object...]
,[... depends ON this missing entity name]
Merci @SQLMonger .. pour me donner la moindre idée de faire la
First query
qui était mon exigence réelle
Cette première requête est PARFAITE! Merci pour ça, c'est génial! Je ne peux pas croire après combien de décennies, MS n'a pas encore construit quelque chose comme ça. Je veux presque prendre cette requête et l'emballer et comprendre comment écrire un plugin SSMS! – eidylon
@eidylon ... C'est génial ... j'en crée un aussi ... aura la mise à jour bientôt .. voici le lien .... https://marketplace.visualstudio.com/items?itemName=MrMKM. Données de base – Moumit
J'ai écrit un script il y a quelques années qui trouveront des procédures stockées ures qui ne compileront pas en tirant le texte du proc et en essayant de le recompiler avec un bloc try/catch. C'est assez simple et efficace pour trouver au moins des procédures qui peuvent être abandonnées. Vous pourriez facilement l'agrandir pour les vues.
Notez que vous ne devez l'exécuter que sur un environnement DEV ou TEST car il tente réellement de recompiler les procédures.
SET NOCOUNT ON
DECLARE @ProcedureName VARCHAR(2048)
DECLARE @ProcedureBody VARCHAR(MAX)
DECLARE @RoutineName varchar(500)
DECLARE procCursor CURSOR STATIC FORWARD_ONLY READ_ONLY
FOR
SELECT
--TOP 1
SCHEMA_NAME(schema_id) + '.' + NAME AS ProcedureName,
OBJECT_DEFINITION(o.[object_id]) AS ProcedureBody
FROM sys.objects AS o
WHERE o.[type] = 'P'
ORDER BY o.[name]
OPEN procCursor
FETCH NEXT FROM procCursor INTO @ProcedureName, @ProcedureBody
WHILE @@FETCH_STATUS = 0
BEGIN
-- Might have to play with this logic if you don't have discipline in your create statements
SET @ProcedureBody = REPLACE(@ProcedureBody, 'CREATE PROCEDURE', 'ALTER PROCEDURE')
BEGIN TRY
EXECUTE(@ProcedureBody)
PRINT @ProcedureName + ' -- Succeeded'
END TRY
BEGIN CATCH
PRINT @ProcedureName + ' -- Failed: ' + ERROR_MESSAGE()
END CATCH
FETCH NEXT FROM procCursor INTO @ProcedureName, @ProcedureBody
END
CLOSE procCursor
DEALLOCATE procCursor
https://brettwgreen.wordpress.com/2012/12/04/find-stored-procedures-that-wont-compile/
À partir de SQL Server 2008, une méthode beaucoup plus simple est ici:
SELECT OBJECT_NAME(referencing_id) AS 'object making reference' ,
referenced_class_desc ,
referenced_schema_name ,
referenced_entity_name AS 'object name referenced' ,
( SELECT object_id
FROM sys.objects
WHERE name = [referenced_entity_name]
) AS 'Object Found?'
FROM sys.sql_expression_dependencies e
LEFT JOIN sys.tables t ON e.referenced_entity_name = t.name;
Comme mentionné dans l'article source (Microsoft MSDN Article on Finding Missing Dependencies), « Une valeur 'NULL' dans le 'objet trouvé? colonne indique que l'objet n'a pas été trouvé dans sys.objects. "
Exemple de sortie:
╔═══════════════════════════════════════════════╦═══════════════════════╦════════════════════════╦═══════════════════════════════════════╦═══════════════╗
║ object making reference ║ referenced_class_desc ║ referenced_schema_name ║ object name referenced ║ Object Found? ║
╠═══════════════════════════════════════════════╬═══════════════════════╬════════════════════════╬═══════════════════════════════════════╬═══════════════╣
║ usvConversationsWithoutServerNotices ║ OBJECT_OR_COLUMN ║ dbo ║ ConversationLinesWithID ║ NULL ║
║ usvFormattedConversationLines_WithSpeakerName ║ OBJECT_OR_COLUMN ║ dbo ║ ConversationLinesWithID ║ NULL ║
║ usvFormattedConversationLines_WithSpeakerName ║ OBJECT_OR_COLUMN ║ dbo ║ FormattedConversationLines_Cached ║ NULL ║
║ udpCheckForDuplicates ║ OBJECT_OR_COLUMN ║ dbo ║ FormattedConversationLines_WithChatID ║ NULL ║
║ usvFormattedConversationsCombined ║ OBJECT_OR_COLUMN ║ dbo ║ GROUP_CONCAT_D ║ 178099675 ║
║ usvSequenceCrossValidationSetStudents ║ OBJECT_OR_COLUMN ║ dbo ║ usvSequenceCrossValidationSet ║ 1406628054 ║
╚═══════════════════════════════════════════════╩═══════════════════════╩════════════════════════╩═══════════════════════════════════════╩═══════════════╝
- 1. Comment trouver des traces dans SQL Server?
- 2. Trouver des emails manquants dans SQL Server
- 3. Comment explorer rapidement des objets dans SQL Server Management Studio
- 4. Stockage des objets binaires dans SQL Server avec LINQ
- 5. objets non-synchronisation DB SQL Server
- 6. Comment trouver la médiane dans SQL Server
- 7. requête SQL Server - trouver d'abord dans l'ordre
- 8. Sql server 2000 -Espace trouver
- 9. Objets utilisés par le travail SQL Server
- 10. T-SQL Hiérarchie pour dupliquer l'arborescence des objets dépendants dans SQL Server 2005
- 11. vs fonctionnalité des extraits brisés 2008
- 12. Architecture de trouver des objets mobiles géolocalisés
- 13. Niveaux d'isolation des transactions MySQL brisés?
- 14. Deny DB objets goutte dans SQL Server 2008
- 15. Obtenir la longueur des colonnes en utilisant des objets SQL Server Management (SMO)
- 16. Trouver Common Phrases dans SQL Server TEXT colonne
- 17. Comment trouver les tables inutilisées dans SQL Server
- 18. SQL Reporting Services - Sous-rapports Brisés en plusieurs colonnes
- 19. SQL: trouver des percentiles
- 20. "Objets système" vs "Objets serveur" dans SQL Server - définitions de termes?
- 21. Caractères accentués brisés dans un lien MailTo
- 22. Trouver des objets entre deux dates MongoDB
- 23. Authentification SQL Server dans SQL Server 2008
- 24. comment trouver qui verrouille qui dans SQL Server 2005
- 25. Fonction pour trouver la correspondance exacte dans Microsoft SQL Server
- 26. Comment trouver les métadonnées WITH RECOMPILE dans SQL Server (2005)?
- 27. employés Trouver spécifiques au service dans SQL Server 2000
- 28. Requête Hibernate: trouver des objets égaux
- 29. Interface Web Mercurial Liens brisés
- 30. Trouver des objets avec belongs_to associations dans Rails?
Il y a une des questions fondamentales avec si vous avez une dynamique SQL - qui pourrait se référer à un objet quelconque, en particulier si elle est combinée avec INFORMATION_SCHEMA. Est-il juste de présumer que votre utilisation du SQL dynamique est assez rare pour que ce ne soit pas un problème? –
Je serais vraiment heureux juste de trouver ceux qui sont statiquement connus pour être manquant. SQL dynamique est un sujet que je ne suis pas prêt à traiter en ce moment. –