【发布时间】:2011-01-31 20:46:59
【问题描述】:
我写了我的 SQL 并遇到了一个问题,请参阅 here。
因此,我正在询问正确的方法来做我想做的事情,而不是我认为的使用 EXEC 的技巧。如果 EXEC 是正确的方法,那么我对 SQL 有疑问,但会使用它。
我正在编写一个 SQL 脚本来创建/更新数据库。我的结构是这样的:
Declare SafetyCheck=0
Declare DBVersion=0
Declare NewInstall=0
Declare DropTables=0
IF SafetyCheck=1
Begin
IF DropTables = 1
Drop all tables in the database
IF Config table doesn't exist
Begin
Create the Config Table
NewInstall = 1
End
IF Other Table doesn't exist
Create the other table
IF Other Table doesn't exist
Create the other table
DBVersion = CheckTheDBVersion
IF DBVersion is old
Begin
Alter tables to make them +1 version higher
Insert some stuff
End
DBVersion = CheckTheDBVersion
IF DBVersion is old
Begin
Alter tables to make them +1 version higher
Insert some stuff
End
IF NewInstall = 1
Begin
Insert default data
End
End
从逻辑上讲,上面应该可以工作,但这不是因为我喜欢上面提到的问题。因此,据我所知,我有 EXEC 或 GO 选项。 EXEC,如上所述,我认为是一个黑客。它将字符串作为 SQL 执行,但我没有以动态方式使用它,我有静态 sql 坐在其中 - 对我来说似乎是错误的。据我所知,GO 会打破一切,因为它会重置变量。
此时我可以选择重新编写 SQL,所以如果我能以正确的方式来做,我会的。我只是不知道我猜的正确方法。
编辑(似乎正在运行的示例脚本):
我不得不分解上面示例中的 SafetyCheck 检查,因为我无法将 GO 放在 IF 语句中。这让它变得更丑陋了。
-- -- --
-- Run this once to create the initial tables
-- -- --
CREATE TABLE Config (
ID [int] IDENTITY(1,1) NOT NULL,
[Key] [nvarchar](255) NOT NULL,
Value [nvarchar](255) NOT NULL
)
ALTER TABLE Config ADD PRIMARY KEY (ID)
CREATE TABLE Roles (
ID [int] IDENTITY(1,1) NOT NULL,
Name [nvarchar](25) NOT NULL,
Created [DateTime] NOT NULL
)
ALTER TABLE Roles ADD PRIMARY KEY (ID)
-- -- --
-- Below, this is the script thats causing errors
-- -- --
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '#v')
DROP TABLE #v
CREATE TABLE #v (n char(30),v char(30))
INSERT INTO #v (n,v) VALUES ('RunSQL', '1') -- Set to 1 or this does nothing
INSERT INTO #v (n,v) VALUES ('DropTables', '0') -- Set to 1 to drop existing tables
-- dont do this for an upgrade
-- dont do this is there are custom tables
GO
IF (SELECT v FROM #v WHERE n='RunSQL') = 0
BEGIN
SELECT 'Nothing has been done. Read First, Run Later' AS Error
END
IF (SELECT v FROM #v WHERE n='RunSQL') = 1
BEGIN
IF (SELECT v FROM #v WHERE n='DropTables') = 1
BEGIN
-- Remove all tables if they exist
EXEC sp_MSforeachtable @command1 = 'DROP TABLE ?'
END
END
GO
IF (SELECT v FROM #v WHERE n='RunSQL') = 1
BEGIN
IF NOT EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Config')
BEGIN
CREATE TABLE Config (
ID [int] IDENTITY(1,1) NOT NULL,
[Key] [nvarchar](255) NOT NULL,
Value [nvarchar](255) NOT NULL
)
ALTER TABLE Config ADD PRIMARY KEY (ID)
-- Assume this is a new database
INSERT INTO Config ([Key], Value) VALUES ('DBVersion', '3')
END
IF NOT EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Roles')
BEGIN
CREATE TABLE Roles (
ID [int] IDENTITY(1,1) NOT NULL,
Name [nvarchar](25) NOT NULL,
Created [DateTime] NOT NULL,
ModifiedDate [DateTime] NOT NULL
)
ALTER TABLE Roles ADD PRIMARY KEY (ID)
END
END
GO
-- Lookup the current verision of the database
IF (SELECT v FROM #v WHERE n='RunSQL') = 1
BEGIN
INSERT INTO #v (n,v) SELECT 'CMSDBVersion', Value FROM Config WHERE [Key]='DBVersion'
END
GO
-- Update old tables to be like the new ones
IF (SELECT v FROM #v WHERE n='RunSQL') = 1
BEGIN
IF (SELECT COUNT(v) FROM #v WHERE n='CMSDBVersion') = 0
BEGIN
-- Add newer fields to exiting tables
ALTER TABLE Roles ADD ModifiedDate DateTime;
INSERT INTO Config ([Key], Value) Values ('DBVersion', '3')
END
END
IF (SELECT v FROM #v WHERE n='RunSQL') = 1
BEGIN
INSERT INTO #v (n,v) SELECT 'CMSDBVersion', Value FROM Config WHERE [Key]='DBVersion'
END
GO
IF (SELECT v FROM #v WHERE n='RunSQL') = 1
BEGIN
IF (SELECT v FROM #v WHERE n='CMSDBVersion') = '3'
BEGIN
-- Add/Update the standard rules
IF NOT EXISTS (SELECT * FROM Roles WHERE Name='CMS User Admin')
INSERT INTO Roles (Name, Created, ModifiedDate) VALUES ('CMS User Admin', GETDATE(), GETDATE())
END
END
GO
-- remove the temp table
DROP TABLE #v
【问题讨论】:
标签: sql sql-server tsql sql-server-2000