【问题标题】:Altering Multiple Tables at once一次更改多个表
【发布时间】:2012-07-12 11:31:15
【问题描述】:

我正在尝试一次更改多个 SQL Server 2008 R2 表。

这是我的代码:

use DatabaseName
go

Declare @SchemaUsed varchar(20) = 'dbo'

create table #Tables
(
  TableName varchar(100), Processed int
)

insert into #Tables 
  select top 1 table_name, 0  
  from INFORMATION_SCHEMA.TABLES 
  where TABLE_SCHEMA = @SchemaUsed
  and table_type = 'Base Table'
  and (TABLE_NAME like 'PM%' )
  ORDER BY TABLE_NAME

DECLARE @TableName varchar(max)
DECLARE @SQL varchar(max)

WHILE EXISTS (select top 1 'x' from #Tables where Processed = 0)
BEGIN
    SET @TableName = (select top 1 TableName from #Tables where Processed = 0)

  Set @SQL = 'ALTER TABLE ' + @SchemaUsed + '.' + @TableName + ' ADD [identityID]  bigint IDENTITY(1, 1) NOT NULL '
 -- Set @SQL =     '''' + @SQL + ''''
  Print @SQL
 EXEC  @SQL;

    update #Tables
    set Processed = 1
    where TableName = @TableName
END

drop table #Tables

我无法使用它来挽救我的生命并出现以下错误:

查找错误 - SQL Server 数据库错误:名称 'ALTER TABLE dbo.PM1GTVLV ADD [identityID] bigint IDENTITY(1, 1) NOT NULL ' 不是 一个有效的标识符。

我也尝试了多种字符串变体,也使用了sp_executesql

谁能指出我哪里出错了?

【问题讨论】:

    标签: tsql sql-server-2008-r2 dynamic-sql


    【解决方案1】:

    要执行字符串,EXEC 需要在字符串(或字符变量)周围加上括号,如BOL syntax 所示:

    EXEC (@SQL);
    

    【讨论】:

      【解决方案2】:

      试试

      DECLARE @SQL NVARCHAR(MAX);
      
      EXEC sp_executesql @SQL;
      

      而不是 EXEC @sql。

      顺便说一句,这是同一代码恕我直言的更有用的版本:

      DECLARE @SchemaUsed VARCHAR(20) = 'dbo';
      
      DECLARE @sql NVARCHAR(MAX) = N'';
      
      SELECT @sql += CHAR(13) + CHAR(10) + N'ALTER TABLE ' 
       + QUOTENAME(@SchemaUsed) + '.'
       + QUOTENAME(name) + ' ADD [identityID]
         BIGINT IDENTITY(1,1) NOT NULL;'
      FROM sys.tables
      WHERE SCHEMA_NAME([schema_id]) = @SchemaUsed
      AND name LIKE 'PM%';
      
      PRINT @sql;
      
      --EXEC sp_executesql @sql;
      

      甚至更好:

      DECLARE @SchemaUsed VARCHAR(20) = 'dbo';
      
      DECLARE @sql NVARCHAR(MAX) = N'';
      
      SELECT @sql += CHAR(13) + CHAR(10) + N'ALTER TABLE ' 
       + QUOTENAME(@SchemaUsed) + '.'
       + QUOTENAME(name) + ' ADD [identityID]
         BIGINT IDENTITY(1,1) NOT NULL;'
      FROM sys.tables AS t
      WHERE SCHEMA_NAME([schema_id]) = @SchemaUsed
      AND name LIKE 'PM%'
      AND NOT EXISTS (SELECT 1 FROM sys.columns AS c
       WHERE [object_id] = t.[object_id]
       AND c.is_identity = 1);
      
      PRINT @sql;
      
      --EXEC sp_executesql @sql;
      

      【讨论】:

      • 我尝试了第二个,它成功了。我想我需要研究 QUOTENAME。谢谢亚伦,当我再次见到你时,我欠你一杯。
      • @David,据我所知,您的错误与QUOTENAME 无关。也就是说,我同意 sp_executesql 通常是比裸 exec 更好的选择。
      • @Tim 我也很难理解这个错误——我可以用EXEC 理解,但问题是他也试过sp_executesql。那里的错误可能与数据类型有关,而不是与无效标识符有关,但我仍然更喜欢这样的版本而不是游标、临时表等。
      • 是的,我也会在循环中设置一组。但是,exec 将与 varchar 一起使用,只是没有括号,它试图将该字符串与存储过程名称匹配(至少在我看来是这样)。
      猜你喜欢
      • 2013-08-23
      • 2012-02-14
      • 2019-08-03
      • 2018-06-19
      • 1970-01-01
      • 1970-01-01
      • 2013-06-24
      • 2021-09-08
      • 2012-07-02
      相关资源
      最近更新 更多