Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如果列不存在于所有表中,是否添加该列?_Sql_Sql Server_Tsql_Sql Server 2008_Alter Table - Fatal编程技术网

Sql 如果列不存在于所有表中,是否添加该列?

Sql 如果列不存在于所有表中,是否添加该列?,sql,sql-server,tsql,sql-server-2008,alter-table,Sql,Sql Server,Tsql,Sql Server 2008,Alter Table,我正在使用SQLServer2005/2008。如果表还不存在,我需要向表中添加一列。这将应用于给定数据库中的所有表。我希望我很接近,但我对这个解决方案有意见 如何做到这一点 以下是我所拥有的: EXEC sp_MSforeachtable ' declare @tblname varchar(255); SET @tblname = PARSENAME("?",1); if not exists (select column_name from INFORMATIO

我正在使用SQLServer2005/2008。如果表还不存在,我需要向表中添加一列。这将应用于给定数据库中的所有表。我希望我很接近,但我对这个解决方案有意见

如何做到这一点

以下是我所拥有的:

EXEC sp_MSforeachtable '
    declare @tblname varchar(255);
    SET @tblname =  PARSENAME("?",1);

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = @tblname and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE @tblname ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'
但我有错误:

错误102:“@tblname”附近的语法不正确。 “CreatedOn”附近的语法不正确。 “@tblname”附近的语法不正确。 “CreatedOn”附近的语法不正确。 ... 等等,每一张桌子


您需要混合一些动态SQL。这应该起作用:

EXEC sp_MSforeachtable '
    declare @tblname varchar(255);
    SET @tblname =  PARSENAME("?",1);
    declare @sql nvarchar(1000);

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = @tblname and column_name = ''CreatedOn'') 
    begin
        set @sql = N''ALTER TABLE '' +  @tblname + N'' ADD CreatedOn datetime NOT NULL DEFAULT getdate();''
        exec sp_executesql @sql
    end
'
也许是这样:

EXEC sp_MSforeachtable '
    declare @tblname varchar(255);
    SET @tblname =  PARSENAME("?",1);

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = @tblname and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'
EXEC sp_MSforeachtable '
    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = ''?'' and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'
?

甚至像这样:

EXEC sp_MSforeachtable '
    declare @tblname varchar(255);
    SET @tblname =  PARSENAME("?",1);

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = @tblname and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'
EXEC sp_MSforeachtable '
    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = ''?'' and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'

不能在DDL中使用变量,如@tableName。此外,将名称分割成部分并忽略模式只会导致错误。你应该用这个?替换SQL批处理参数,并依赖MSforeachtable替换:

EXEC sp_MSforeachtable '
if not exists (select * from sys.columns 
               where object_id = object_id(''?'')
               and name = ''CreatedOn'') 
begin
    ALTER TABLE ? ADD CreatedOn datetime NOT NULL DEFAULT getdate();
end';

@JAiro:这肯定是一个相关链接,但if not exists规则很重要,使其更复杂。好的,您可以用这个来完成信息:问题的根本原因是依赖于信息\u SCHEMA视图,必须将名称拆分为SCHEMA和object。只使用对象id?你会没事的。更快速的检查是COLUMNPROPERTYobject_id?,CreatedOn,ColumnId是否为空。-1显然在发布之前没有测试过这一点。[?]在已用括号括起来的名称周围添加括号,导致[[schemaname].[tablename]]不正确。@Remus Rusanu:我测试过这个:sp_MSforeachtable'EXEC sp_help?;EXEC sp_列?'。这就产生了语法错误。然后我将其更改为sp_MSforeachtable'EXEC sp_help[?];EXEC sp_列[?]”,它可以运行SQL Server 2008 R2…但是您没有测试OP ALTER表[?]。sp_help和sp_列都是存储过程,而?替换无效,因为sp_help[foo].[bar]的语法无效。但是sp_help[[foo]].[bar]]]是正确的语法,并且由于参数的处理方式,它实际上最终会起作用。但ALTER TABLE[[foo]].[bar]]]不起作用。长话短说:你发布的代码没有通过基本的语法检查,这可以被任何人验证。@Remus Rusanu:我不是在争论。我发布我的测试示例有两个原因:一是提供我产生错觉的原因,二是除了我无知的明显原因外,可能还有人解释我为什么会被欺骗。所以,最后,谢谢你哦,sry,然后我误解了你的评论。sp_help[?]的工作方式至少让我感到困惑。@Remus:是的,如果OP使用的是模式,那么这就成了一个问题+请记住,sp_msforeachtable是一个不受支持的存储过程,因此不应将其用于生产代码。虽然它添加了几行代码,但如果使用定义为select from sys.SCHEMA和sys.tables的游标,您使用的是T-SQL的文档部分,您可以选择仅通过更改WHERE表达式来影响所有或部分表,并且性能相同。此外,如果使用quotename函数,则需要处理的名称限定符也较少。最后,您在使用模式/表名时有更大的灵活性,不管您希望怎样,也就是日志。@菲利默尔,连同一个例子,将做出一个很好的回答。考虑给您的答案添加解释。可能也会删除代码的屏幕截图…嗨,Jean,实际上我只是将列名存储在一个变量中,并找出该特定列不存在的表名,然后将alter命令保存在另一个变量@sql中,我们运行该变量来执行添加。