是否有T-SQL命令检查同义词所引用的对象是否存在且有效?

前端之家收集整理的这篇文章主要介绍了是否有T-SQL命令检查同义词所引用的对象是否存在且有效?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用下面的sql批处理脚本测试数据库中的所有同义词是否引用有效对象,作为我们数据库清理工作的一部分.此脚本只对同义词执行查询,并打印出遇到的任何错误.这适用于视图和表,但不适用于sprocs.
  1. SET NOCOUNT ON
  2.  
  3. DECLARE @currentId INT;
  4. DECLARE @currentSynonym VARCHAR(255);
  5.  
  6. SELECT @currentId = MIN(id) FROM sysobjects WITH (NOLOCK) WHERE [xtype]='SN';
  7.  
  8. WHILE @currentId IS NOT NULL
  9. BEGIN
  10. SELECT TOP(1) @currentSynonym = name FROM sysobjects WITH (NOLOCK) WHERE id = @currentId;
  11.  
  12. PRINT '';
  13. PRINT '------------------------------------------------------------';
  14. PRINT @currentSynonym;
  15. PRINT '------------------------------------------------------------';
  16.  
  17. BEGIN TRY
  18. EXEC('SELECT Top(1) NULL FROM ' + @currentSynonym + ' WITH (NOLOCK);');
  19. PRINT 'Synonym is valid.';
  20. END TRY
  21. BEGIN CATCH
  22. PRINT ERROR_MESSAGE();
  23. END CATCH
  24.  
  25. SELECT @currentId = MIN(id) FROM sysobjects WITH (NOLOCK) WHERE [xtype]='SN' AND id > @currentId;
  26. END
  27.  
  28. SET NOCOUNT OFF

是否有一个命令可以在sproc,table或view上执行,如果它不存在会抛出错误

同义词可以指向链接服务器上的对象,也可以指向当前@@ SERVERNAME上的对象,因此我不能真正只查询catch块中的sys.procedures以查看它是否存在.我必须知道同义词是否指向链接服务器,然后我必须查询该服务器的sys.procedures视图.

我发现了一个类似的问题,How can I check if the table behind a synonym exists,但它并不是我所要求的.我发现的其他所有内容都是Oracle特有的.

更新:下面的脚本适合我的需要.感谢@ kenny-evitt获取我需要的信息.

  1. SET NOCOUNT ON
  2.  
  3. DECLARE -- for looping through sys.synonyms
  4. @currentSynonym VARCHAR(255),-- for parsing out [ServerName].[DatabaseName].[SchemaName].[ObjectName] from sys.synonyms.base_object_name
  5. @baSEObjectName NVARCHAR(1035),@lastDelimiterIndex INT,@lastToken NVARCHAR(255),@sServer NVARCHAR (255),@sDatabase NVARCHAR(255),@sSchema NVARCHAR(255),@sObject NVARCHAR(255),-- for testing if synonym points to an existing object
  6. @sql NVARCHAR(1035),@objectCount INT,-- for output formatting
  7. @newLine NVARCHAR(2),@tab NVARCHAR(4),@validSynonyms NVARCHAR(MAX),@invalidSynonyms NVARCHAR(MAX);
  8.  
  9. SET @validSynonyms = '';
  10. SET @invalidSynonyms = '';
  11. SET @newLine = CHAR(13) + CHAR(10);
  12. SET @tab = ' ';
  13.  
  14. /* Loop through this DB's sys.synonyms view */
  15. SELECT @currentSynonym = MIN(name) FROM sys.synonyms WITH (NOLOCK);
  16.  
  17. WHILE @currentSynonym IS NOT NULL
  18. BEGIN
  19. SET @sObject = NULL;
  20. SET @sSchema = NULL;
  21. SET @sDatabase = NULL;
  22. SET @sServer = NULL;
  23.  
  24. /* Parse out [server].[database].[schema].[object] from sys.synonyms.base_object_name */
  25. SELECT @baSEObjectName = RTRIM(base_object_name) FROM sys.synonyms WITH (NOLOCK) WHERE name = @currentSynonym;
  26.  
  27. WHILE LEN(@baSEObjectName) > 0
  28. BEGIN
  29. SET @lastToken = NULL;
  30. SET @lastDelimiterIndex = CHARINDEX('.',@baSEObjectName,1) + 1;
  31.  
  32. -- Find the last token in @manipulated string,-- Do this Right-to-Left,as the database and/or server may not be in sys.synonyms.base_object_name
  33. WHILE (CHARINDEX('.',@lastDelimiterIndex) > 0)
  34. BEGIN
  35. SET @lastDelimiterIndex = CHARINDEX('.',@lastDelimiterIndex) + 1;
  36. END
  37. SET @lastToken = SUBSTRING(@baSEObjectName,@lastDelimiterIndex - 1,LEN(@baSEObjectName) - @lastDelimiterIndex + 3);
  38.  
  39. -- Kind of kludgy,but I put the $character at the end of the string and @lastToken,-- so that if 2 of the values match (i.e. object and database,object and schema,whatever) only the last one
  40. -- is replaced.
  41. SET @lastToken = @lastToken + '$';
  42. SET @baSEObjectName = @baSEObjectName + '$';
  43. SET @baSEObjectName = REPLACE(@baSEObjectName,@lastToken,'');
  44.  
  45. SET @lastToken = REPLACE(@lastToken,'.','');
  46. SET @lastToken = REPLACE(@lastToken,'[',']','$','');
  47.  
  48. IF @sObject IS NULL
  49. SET @sObject = @lastToken;
  50. ELSE IF @sSchema IS NULL
  51. SET @sSchema = @lastToken;
  52. ELSE IF @sDatabase IS NULL
  53. SET @sDatabase = @lastToken;
  54. ELSE IF @sServer IS NULL
  55. SET @sServer = @lastToken;
  56. END
  57.  
  58. IF @sDatabase IS NULL
  59. SET @sDatabase = DB_NAME();
  60. IF @sServer IS NULL
  61. SET @sServer = @@SERVERNAME;
  62.  
  63. /* End of token sys.synonyms.base_object_name parsing */
  64.  
  65. /* Query for the existence of the object on the database the synonym's object should be on. */
  66. BEGIN TRY
  67. SET @sql = N'SELECT @count = Count(1) FROM [' + @sServer + '].[' + @sDatabase + '].sys.sysobjects WITH (NOLOCK) WHERE [name] = ''' + @sObject + ''';';
  68.  
  69. EXECUTE sp_executesql @sql,N'@count INT OUTPUT',@count = @objectCount OUTPUT;
  70.  
  71. If @objectCount > 0
  72. SET @validSynonyms = @validSynonyms + @tab + N'* ' + @currentSynonym + @newLine;
  73. ELSE
  74. SET @invalidSynonyms = @invalidSynonyms + @tab + N'* ' + @currentSynonym + @newLine;
  75. END TRY
  76. BEGIN CATCH
  77. SET @invalidSynonyms = @invalidSynonyms + @tab + N'* ' + @currentSynonym + ' =>' + @newLine;
  78. SET @invalidSynonyms = @invalidSynonyms + @tab + @tab + ERROR_MESSAGE() + @newLine;
  79. END CATCH
  80.  
  81.  
  82. SELECT @currentSynonym = MIN(name) FROM sys.synonyms WITH (NOLOCK) WHERE name > @currentSynonym;
  83. END
  84. /*End of sys.synonym Loop*/
  85.  
  86. PRINT 'Invalid Synonyms:' + @newLine + @newLine;
  87. PRINT @invalidSynonyms;
  88. PRINT @newLine + 'Valid Synonyms:' + @newLine + @newline;
  89. PRINT @validSynonyms;
  90.  
  91.  
  92. SET NOCOUNT OFF

解决方法

没有内置的命令/功能/等等,你可以写一个.我建议使用另一种语言而不是T-sql,但它确实可以单独使用.

您需要解析系统目录视图sys.synonyms中base_object_name列中的值.

猜你在找的MsSQL相关文章