SQL - 在 IF NOT EXISTS 后添加列和设置值
SQL - Add column and set value after IF NOT EXISTS
如果列不存在,我在使用 Alter Table 时遇到问题。
这是我的代码:
DECLARE @appId INT
DECLARE @cursor CURSOR
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'MinMktIdeaParticipants' AND TABLE_NAME = 'mkIdeaCategories')
BEGIN
ALTER TABLE mkIdeaCategories
ADD MinMktIdeaParticipants int NOT NULL DEFAULT 1
END
IF EXISTS(SELECT Value FROM appConfiguration WHERE CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10)
BEGIN
SET @cursor = CURSOR FAST_FORWARD
FOR
SELECT ApplicationId FROM mkMarket
OPEN @cursor
FETCH NEXT FROM @cursor INTO @appId
WHILE (@@Fetch_Status >= 0)
BEGIN
UPDATE
mkIdeaCategories
SET MinMktIdeaParticipants = (SELECT Value FROM appConfiguration
WHERE ApplicationId = @appId AND CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10)
WHERE IdeaCatId IN
(select distinct(theme.IdeaCatId) from dbo.mkIdeaCategories theme
inner join dbo.mkMarketIdeaCategories mic ON theme.IdeaCatId = mic.IdeaCatId
inner join mkMarket m on m.MarketId=mic.MarketId
WHERE m.ApplicationId = @appId)
FETCH NEXT FROM @cursor INTO @appId
END
CLOSE @cursor
DEALLOCATE @cursor
DELETE * FROM appConfiguration WHERE CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10
END
我认为没有任何错误。由于某种原因,输出错误是
Msg 207, Level 16, State 1, Line 53
Invalid column name 'MinMktIdeaParticipants'.
我已经搜索过类似的问题,但找不到解决问题的答案。
当SQL 服务器处理脚本时,有两个阶段。第一阶段是编译。二是执行。
您遇到的错误是编译错误。 All 代码被编译,而不管 if
条件。因此,您会收到错误消息,因为该列不存在。直到执行阶段才会创建该列。
一个解决方案是将代码的第二部分更改为动态 SQL,使用 exec
(或更好的 exec sp_executesql
)来执行代码。
Gordon Linoff 的解决方案会奏效。另一种实现您想要的方法是将整个语句包装在存储过程中。
这会失败:
select * from nonexisting_table
这将创建一个存储过程:
create procedure nonsense
as
begin
select * from nonexisting_table
end
但是您的查询有错误:
SET @cursor = CURSOR FAST_FORWARD
要在 sql 服务器中创建快进游标,您必须声明它。
那是我最喜欢的例子 mssqltips.com:
DECLARE db_cursor CURSOR FAST_FORWARD FOR
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @fileName = @path + @name + '_' + @fileDate + '.BAK'
BACKUP DATABASE @name TO DISK = @fileName
FETCH NEXT FROM db_cursor INTO @name
END
CLOSE db_cursor
DEALLOCATE db_cursor
如果列不存在,我在使用 Alter Table 时遇到问题。
这是我的代码:
DECLARE @appId INT
DECLARE @cursor CURSOR
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'MinMktIdeaParticipants' AND TABLE_NAME = 'mkIdeaCategories')
BEGIN
ALTER TABLE mkIdeaCategories
ADD MinMktIdeaParticipants int NOT NULL DEFAULT 1
END
IF EXISTS(SELECT Value FROM appConfiguration WHERE CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10)
BEGIN
SET @cursor = CURSOR FAST_FORWARD
FOR
SELECT ApplicationId FROM mkMarket
OPEN @cursor
FETCH NEXT FROM @cursor INTO @appId
WHILE (@@Fetch_Status >= 0)
BEGIN
UPDATE
mkIdeaCategories
SET MinMktIdeaParticipants = (SELECT Value FROM appConfiguration
WHERE ApplicationId = @appId AND CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10)
WHERE IdeaCatId IN
(select distinct(theme.IdeaCatId) from dbo.mkIdeaCategories theme
inner join dbo.mkMarketIdeaCategories mic ON theme.IdeaCatId = mic.IdeaCatId
inner join mkMarket m on m.MarketId=mic.MarketId
WHERE m.ApplicationId = @appId)
FETCH NEXT FROM @cursor INTO @appId
END
CLOSE @cursor
DEALLOCATE @cursor
DELETE * FROM appConfiguration WHERE CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10
END
我认为没有任何错误。由于某种原因,输出错误是
Msg 207, Level 16, State 1, Line 53
Invalid column name 'MinMktIdeaParticipants'.
我已经搜索过类似的问题,但找不到解决问题的答案。
当SQL 服务器处理脚本时,有两个阶段。第一阶段是编译。二是执行。
您遇到的错误是编译错误。 All 代码被编译,而不管 if
条件。因此,您会收到错误消息,因为该列不存在。直到执行阶段才会创建该列。
一个解决方案是将代码的第二部分更改为动态 SQL,使用 exec
(或更好的 exec sp_executesql
)来执行代码。
Gordon Linoff 的解决方案会奏效。另一种实现您想要的方法是将整个语句包装在存储过程中。
这会失败:
select * from nonexisting_table
这将创建一个存储过程:
create procedure nonsense
as
begin
select * from nonexisting_table
end
但是您的查询有错误:
SET @cursor = CURSOR FAST_FORWARD
要在 sql 服务器中创建快进游标,您必须声明它。 那是我最喜欢的例子 mssqltips.com:
DECLARE db_cursor CURSOR FAST_FORWARD FOR
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @fileName = @path + @name + '_' + @fileDate + '.BAK'
BACKUP DATABASE @name TO DISK = @fileName
FETCH NEXT FROM db_cursor INTO @name
END
CLOSE db_cursor
DEALLOCATE db_cursor