更改多个表

one*_*com 3 sql-server alter-table sql-server-2012

我在 mssql 2012 中拥有包含 170 多个表的数据库。其中一些包含字段“UserID”、varchar(9) 而另一些则不包含。由于应用程序重新设计,我需要更改数据库中的所有表以检查该字段是否存在,如果存在,我需要将其更改为 varchar(50)。如果没有,那么我需要添加它。

有人可以指出我如何使用某种批处理程序来做到这一点吗?我对 mssql 数据库没有太多经验,因此将不胜感激。

Aar*_*and 7

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

SELECT @sql += [sql] FROM
(
  SELECT [sql] = N'
  ALTER TABLE '
    + QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
    + ' ALTER COLUMN ' + c.name + ' VARCHAR(50);'
  FROM sys.columns AS c
  INNER JOIN sys.tables AS t
  ON c.[object_id] = t.[object_id]
  INNER JOIN sys.schemas AS s
  ON t.[schema_id] = s.[schema_id]
  WHERE LOWER(c.name) = N'userid'
  AND c.max_length < 50
  UNION ALL 
  SELECT N'
  ALTER TABLE '
    + QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
    + ' ADD UserID VARCHAR(50);'
  FROM sys.tables AS t
  INNER JOIN sys.schemas AS s
  ON t.[schema_id] = s.[schema_id]
  WHERE NOT EXISTS
  (
   SELECT 1 FROM sys.columns 
     WHERE LOWER(name) = N'userid'
     AND [object_id] = t.[object_id]
  )
) AS x;

PRINT @sql;

--EXEC sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)

如果字符串太长而无法通过 PRINT 正确验证,请参阅此提示以了解其他想法

您还需要确保更新任何将其作为varchar(9)参数的存储过程,因为这些过程会以静默方式截断,以及您在即席 SQL、视图和其他模块等中执行的任何显式转换或变量声明。例如,如果您有两个用户,一个 ID = frankenstein,另一个只是frankenst

DECLARE @UserID VARCHAR(9) = 'frankenstein';
SELECT @UserID;
Run Code Online (Sandbox Code Playgroud)

结果:

frankenst -- this will match the wrong user!
Run Code Online (Sandbox Code Playgroud)

  • +1 如果列不存在,则完全错过添加列的部分。这个答案是完整和正确的。 (2认同)

Tho*_*ger 6

这是一个执行以下操作的查询:

use YourDatabase;
go

select
    object_name = 
        object_name(c.object_id),
    column_name = c.name,
    type_name = t.name,
    c.max_length,
    alter_table_ddl = 
        'alter table ' + 
        quotename(object_schema_name(c.object_id)) + '.' + 
        quotename(object_name(c.object_id)) + 
        ' alter column ' + quotename(c.name) + 
        ' varchar(50);'
from sys.columns c
inner join sys.types t
on c.system_type_id = t.system_type_id
where c.name = 'UserID'
--and c.max_length = 9;
Run Code Online (Sandbox Code Playgroud)

您可以取消注释最后一行(用于过滤的 AND 子句)以仅提取数据库中 varchar(9) 的列。

因此,此查询将标识您关注的列,并且查询结果集的最后一列将是ALTER TABLE ... ALTER COLUMNDDL,它应该是进行列更改的 T-SQL 文本。

听起来这可能是一个非生产环境/数据库,但值得一提的是,要实际进行所有这些更改,此操作可能具有极大的侵入性。无论哪种方式,请确保最终用户的影响最小,并确保您在执行此操作之前拥有此数据库的有效备份。同样,查看查询的输出。永远不要只获取输出,尤其是生成 DDL 的输出,然后盲目地执行它

编辑:我完全错过了您的问题的一部分,如果该列不存在,您的要求也是添加该列。抱歉,我不会重做 Aaron 的工作,因为他似乎已经满足了该要求。