對於我們的SQL Server數據庫,我們使用版本控制方案來跟蹤模式更新。這個想法是,你應該能夠運行這個腳本,將模式從任何以前的版本升級到當前版本。再次運行主腳本應該只執行最新的模式更新。T-SQL「可重新運行」數據庫更新腳本 - 刪除列
劇本的結構是這樣的:
SELECT @Installed = InstallDate FROM SystemSchemaVersion WHERE Major=1 AND Minor=0 AND Patch=0
IF (@Installed IS NULL)
BEGIN
...
INSERT INTO SystemSchemaVersion (Major, Minor, Patch, InstallDate) VALUES (1, 0, 0, GetDate())
END
ELSE PRINT 'Version 1.0.0 was already installed on ' + Convert(varchar(10), @Installed)
SELECT @Installed = InstallDate FROM SystemSchemaVersion WHERE Major=1 AND Minor=0 AND Patch=1
IF (@Installed IS NULL)
BEGIN
...
INSERT INTO SystemSchemaVersion (Major, Minor, Patch, InstallDate) VALUES (1, 0, 1, GetDate())
END
ELSE PRINT 'Version 1.0.1 was already installed on ' + Convert(varchar(10), @Installed)
這通常工作得很好。但是,當模式更新DROP包含在前一個INSERT中的列時,我們遇到了一個問題;也就是說,我們有這樣的東西:
SELECT @Installed = InstallDate FROM SystemSchemaVersion WHERE Major=1 AND Minor=0 AND Patch=0
IF (@Installed IS NULL)
BEGIN
INSERT [foo] ([a], [b], [OrganizationId]) VALUES (N'a', N'b', N'1');
INSERT INTO SystemSchemaVersion (Major, Minor, Patch, InstallDate) VALUES (1, 0, 0, GetDate());
END
ELSE PRINT 'Version 1.0.0 was already installed on ' + Convert(varchar(10), @Installed)
SELECT @Installed = InstallDate FROM SystemSchemaVersion WHERE Major=1 AND Minor=0 AND Patch=1
IF (@Installed IS NULL)
BEGIN
ALTER TABLE [foo] DROP COLUMN [OrganizationId];
INSERT INTO SystemSchemaVersion (Major, Minor, Patch, InstallDate) VALUES (1, 0, 1, GetDate());
END
ELSE PRINT 'Version 1.0.1 was already installed on ' + Convert(varchar(10), @Installed)
這工作正常,它第一次執行;版本1.0.1被執行,並且該列被刪除。然而,運行腳本第二次產量:
Msg 207, Level 16, State 1, Line 7118 Invalid column name 'OrganizationId'.
也就是說,即使沒有被執行版本1.0.0塊內的INSERT,它仍然被解析併產生了無效的列錯誤。
有關如何解決此問題的任何建議?理想情況下,我希望使用條件保護INSERT,以便它甚至不被解析,但似乎沒有發生。我可以在sp_ExecuteSql()調用內動態執行INSERT,但我不想(需要大量的改進)。
謝謝 -
--Andy
謝謝,羅恩。我希望能有一種替代方案來編輯一堆現有的生成腳本,但至少有一條路向前進。 – 2009-08-27 17:05:41