2010-08-11 41 views
4

我对SQL相当陌生,所以不确定这只是一个SQL编译器的东西。当我在通过JAVA或PHP之前使用SQL时,绝不仅仅是直接的SQL。我正在使用SQL Server 2005并试图将一列添加到我的表中,然后填充它。以下是我现在有:列的创建和使用

ALTER TABLE House DROP COLUMN CustomerType 
ALTER TABLE House ADD CustomerType char(11) 

UPDATE House 
SET CustomerType = CASE 
    WHEN ... THEN... 
    WHEN ... THEN... 
    ELSE "Other" 
    END 

然而,当我试图在UPDATE功能编译尚未确定,因为这CustomerType它的错误。有没有什么办法来运行它,以便编译和添加列并更新它,还是我必须在多个执行中运行它?

谢谢!

+0

看起来不错。当所有人一次运行时应该工作。使用脚本顶部的USE关键字来告诉它要使用哪个数据库是一种很好的做法。例如使用dbo.database1。 – 2010-08-11 15:45:18

回答

9

使用多个文件的每一个操作,或将“GO”的步骤之间:

ALTER TABLE House DROP COLUMN CustomerType 
GO 

ALTER TABLE House ADD CustomerType char(11) 
GO 

UPDATE House 
SET CustomerType = CASE 
    WHEN ... THEN... 
    WHEN ... THEN... 
    ELSE "Other" 
    END 
GO 

这个工作在SQL Server Management Studio中 - 它不是一个T-SQL的功能,但管理工作室的功能,分开SQL命令的T-SQL“批处理”。

更新:如果你想让你的脚本可以多次运行,更有用的方法是检查列的存在,只有当它不存在时才添加它 - 没有如果它已经在那里,请始终删除并重新添加它!

要做到这一点,使用类似:

IF NOT EXISTS(SELECT * FROM sys.columns WHERE name = 'CustomerType' 
         AND object_id = OBJECT_ID('House')) 
    ALTER TABLE dbo.House ADD CustomerType CHAR(11) 
GO 

的这段代码检查SQL目录视图sys.columns,看看是否列在表已经存在 - 如果不是,它的创建。当您在表中运行此代码一千次时,第一次创建该列时,随后的任何运行都不会执行任何操作 - 因为该列已经存在。比不断滴加和重新添加色谱柱要干净得多!

+0

谢谢!工作很棒! – user416516 2010-08-11 15:53:48

+1

多个文件 - DDL和DML应该是分开的。 – duffymo 2010-08-11 20:12:45

4

尝试在第二个ALTER声明之后并在您的UPDATE声明之前放置GO声明。

1

也许您必须在执行UPDATE之前将更改提交到模式。

模式DDL应该在您到达DML/DQL时解决。你为什么认为你必须不断下降并添加该列?

+0

我只是放弃它并添加它,因为脚本必须多次运行才有可能。我不想每次都创建一个新列。所以我认为这只会重置整个过程。有没有更干净的方法呢? – user416516 2010-08-11 15:56:41

+0

@shavus你可以使用'IF columnproperty(object_id('dbo.House'),'street','ColumnId')IS NULL ALTER TABLE House ADD CustomerType char(11)' – 2010-08-11 16:18:59

1

还有比你上面显示的更多。我无法得到一个非常相似的脚本失败;下面的作品好了:

CREATE TABLE #House (housekey int, number int, street char(20)) 

insert into #House (housekey, number, street) values (1, 123, 'Wilson Ave') 
insert into #House (housekey, number, street) values (2, 124, 'Wilson Ave') 
insert into #House (housekey, number, street) values (3, 125, 'Wilson Ave') 

alter table #House DROP COLUMN street 
alter table #House ADD street varchar(20) 

update #House 
set street = case 
    when number = 123 then 'Wilson Ave' 
    when number = 124 then 'Willson Ave' 
    when number = 125 then 'Wulson Ave' 
    else 'Xxy St' 
end 

select * from #house 

drop table #house 

我想通过把“GO”后,某些部分将是有效的,但是当我来运行的东西我不能让它失败分手剧本的想法。

换句话说,“它适用于我的机器。”你有什么可以改变的吗?

编辑添加:是的,GO是答案。我承认,“它在我的机器上运行”在这里有点不负责任,因为这个问题没有涉及临时表格 - 而是一个常规表格。我用永久性表格试验了这个问题,并得到了与提问者相同的结果,GO固定了它。事实上,这似乎是合乎逻辑的。

+1

不可以。因为整个表不存在你得到延期编译。尝试针对尚未包含“街道”列的现有表执行此操作。编辑呃。其实我只是做了,并没有发生。 SQL2000兼容模式可能?我会做更多的测试! – 2010-08-11 15:59:03

+0

是的,我的表格还没有'CustomerType'列。这将像你把'alter table #House DROP COLUMN zipcode' – user416516 2010-08-11 16:03:34

+0

@ shavus1988 - 你的数据库在SQL2000兼容模式下吗? – 2010-08-11 16:05:13