2013-04-23 43 views
0

我需要使用特定前缀搜索某些数据库。一旦找到这些数据库,我需要检查某个特定的模式是否存在,以及它是否存在 - 使数据库脱机。我一直在尝试在Google上发现的各种建议,但没有任何效果。我有一个我无法逾越的错误。错误是'XYZ'不是公认的选项。如果我将代码分离出来,它运行良好,但是当我添加sp_MSforeachdb时,错误会返回。如何在sp_MSforeachdb中指定TABLE_SCHEMA名称以使数据库脱机

EXEC sp_msforeachdb 'IF ''?'' LIKE ''abc_%'' 
    BEGIN 
     IF (NOT EXISTS (SELECT * 
       FROM INFORMATION_SCHEMA.TABLES 
       WHERE TABLE_SCHEMA = 'XYZ'   
           BEGIN 
           ALTER DATABASE [abc_xxxxxxxxx] SET OFFLINE WITH 
           ROLLBACK IMMEDIATE    
           END' 

此代码工作正常:

SELECT * 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA = 'XYZ' 
+0

回答1工作的罚款和第二反应也有帮助。我决定实施第一种解决方案,因为它不依赖于sp_MSforeachdb。感谢所有贡献的人! – user1927354 2013-04-25 01:27:39

回答

4

下面是一个不依赖于undocumented, unsupported and buggy system procedure sp_msforeachdb的方法,也并不依赖于similarly unreliable INFORMATION_SCHEMA views

DECLARE @sql NVARCHAR(MAX); 
SET @sql = N''; 

SELECT @sql = @sql + N'IF NOT EXISTS (SELECT 1 FROM ' 
    + QUOTENAME(name) + '.sys.tables AS t 
    INNER JOIN ' + QUOTENAME(name) + '.sys.schemas AS s 
    ON t.schema_id = s.schema_id 
    WHERE s.name = ''XYZ'') 
    BEGIN 
    EXEC sp_executesql N''ALTER DATABASE ' 
     + QUOTENAME(name) + ' SET OFFLINE;'' 
    END 
' FROM sys.databases WHERE name LIKE 'abc_%'; 

PRINT @sql; 
-- EXEC sp_executesql @sql; 

您的实际错误是因为您在字符串中有字符串分隔符。你可以这样做:

SELECT ' WHERE TABLE_SCHEMA = 'XYZ' ... '; 

错误:

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ' ... '.

你需要这样做:很快

SELECT ' WHERE TABLE_SCHEMA = ''XYZ'' ... '; 

然而,这被曲,当你里面嵌套一个命令命令你发送到一个无证,不受支持和有问题的系统过程。我知道我在这里重复自己。我希望很明显,如果你想获得可靠的结果,你不应该使用sp_msforeachdb

0

你有一些小错误

EXEC sp_msforeachdb ' 
IF ''?'' LIKE ''abc_%'' 
    BEGIN 
     IF NOT EXISTS (SELECT * 
         FROM INFORMATION_SCHEMA.TABLES 
         WHERE TABLE_SCHEMA = ''XYZ'') 
      ALTER DATABASE [abc_xxxxxxxxx] SET OFFLINE WITH ROLLBACK IMMEDIATE    
    END' 
  1. 你逃脱周围''?''''abc_%''引号,但忘了'XYZ'
  2. 括号不匹配的 - 你有两个开放括号,但没有关闭括号
  3. ALTER DATABASE语句是单行,不需要BEGIN-END。删除BEGIN允许END匹配其他BEGIN,但您可以完全删除BEGIN-END。
0

尝试这一个 -

DECLARE 
     @schema_name SYSNAME 
    , @database_name SYSNAME 

SELECT 
     @schema_name = 'XYZ' 
    --, @database_name = 'abc_%' 

DECLARE @SQL NVARCHAR(MAX) 

SELECT @SQL = (SELECT ' 
USE [' + d.name + ']; 
IF NOT EXISTS (
    SELECT 1 
    FROM sys.objects o 
    JOIN sys.schemas s ON o.[schema_id] = s.[schema_id] 
    WHERE o.type = ''U'' 
     AND s.name = ''' + @schema_name + ''' 
) EXEC sp_executesql N''ALTER DATABASE [' + d.name + '] SET OFFLINE;'' 
' 
FROM sys.databases d 
WHERE (@database_name IS NULL OR d.name LIKE @database_name) 
    AND d.[state] = 0 
    AND d.name NOT IN ('master', 'tempdb', 'model', 'msdb') 
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 

EXEC sp_executesql @sql 
相关问题