SQL: BEGIN 和 END 中的多个语句
SQL: multiple statements within a BEGIN and END
我正在尝试向现有的 table 添加一个新列,该列将由唯一的 Guid 值填充。我正在尝试以下代码:
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NULL
UPDATE dbo.Product
SET Product_Guid=NEWID()
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
END
这行不通,因为第二条语句无法识别新的列名。我不能放 GO 或 ;不过在每个语句的末尾,大概是因为我在 BEGIN/END 块的中间。
解决这个难题的最佳方法是什么?
您似乎想要设置默认值并让该列不为空。如果您将默认值设置为 NEWID()
,您将获得相同的效果
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NOT NULL DEFAULT NEWID()
END
如果之后需要删除约束,可以在 alter 语句中定义列后创建 DEFAULT 约束,然后立即删除命名约束。如果您不命名约束,则必须从 sys.objects 获取名称,然后执行动态 sql 将其删除。
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NOT NULL,
CONSTRAINT Default_Product_GUID DEFAULT NEWID() FOR Product_GUID;
ALTER TABLE dbo.Product DROP CONSTRAINT Default_Product_GUID
END
执行更新的语句必须在添加列后编译。
通常的做法是将语句包装在 EXEC
:
EXEC(' UPDATE dbo.Product
SET Product_Guid = NEWID()
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
')
您可以稍后更新 table,然后在另一个代码块中更改它,有点像这样:
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NULL
END
GO
UPDATE dbo.Product
SET Product_Guid=NEWID()
Where Product_Guid is null
if @@ROWCOUNT <> 0
Begin
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
End
我正在尝试向现有的 table 添加一个新列,该列将由唯一的 Guid 值填充。我正在尝试以下代码:
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NULL
UPDATE dbo.Product
SET Product_Guid=NEWID()
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
END
这行不通,因为第二条语句无法识别新的列名。我不能放 GO 或 ;不过在每个语句的末尾,大概是因为我在 BEGIN/END 块的中间。
解决这个难题的最佳方法是什么?
您似乎想要设置默认值并让该列不为空。如果您将默认值设置为 NEWID()
,您将获得相同的效果IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NOT NULL DEFAULT NEWID()
END
如果之后需要删除约束,可以在 alter 语句中定义列后创建 DEFAULT 约束,然后立即删除命名约束。如果您不命名约束,则必须从 sys.objects 获取名称,然后执行动态 sql 将其删除。
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NOT NULL,
CONSTRAINT Default_Product_GUID DEFAULT NEWID() FOR Product_GUID;
ALTER TABLE dbo.Product DROP CONSTRAINT Default_Product_GUID
END
执行更新的语句必须在添加列后编译。
通常的做法是将语句包装在 EXEC
:
EXEC(' UPDATE dbo.Product
SET Product_Guid = NEWID()
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
')
您可以稍后更新 table,然后在另一个代码块中更改它,有点像这样:
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NULL
END
GO
UPDATE dbo.Product
SET Product_Guid=NEWID()
Where Product_Guid is null
if @@ROWCOUNT <> 0
Begin
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
End