2010-08-11 43 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