Sql server 使用游标为条件逻辑提取单行,根据所述逻辑计算新列
对不起,如果这是荒谬的基本。我正在尝试编写一个SQL 2012存储过程,它可以根据存储在一行中的一系列问题的答案计算分数。然后,我想将计算出的分数作为一个额外的列添加到存储过程中 这用于SQL Server Reporting Services管理的报表中 我在下面编写了测试查询:Sql server 使用游标为条件逻辑提取单行,根据所述逻辑计算新列,sql-server,stored-procedures,cursor,Sql Server,Stored Procedures,Cursor,对不起,如果这是荒谬的基本。我正在尝试编写一个SQL 2012存储过程,它可以根据存储在一行中的一系列问题的答案计算分数。然后,我想将计算出的分数作为一个额外的列添加到存储过程中 这用于SQL Server Reporting Services管理的报表中 我在下面编写了测试查询: -- Test query to perform conditional logic on individual table rows stored in a cursor, and use this logic t
-- Test query to perform conditional logic on individual table rows stored in a cursor, and use this logic to calculate a value assigned to the same cursor row. GOAT FOR THE GOAT GODS--
DECLARE @Goat int = 0
DECLARE @Goatkey1 varchar
DECLARE @Goatkey2 varchar
SELECT Goatsight
FROM [Goat].[dbo].[Goat1]
DECLARE Goatcurse CURSOR
FOR
SELECT [GOAT?], [GOATSE]
FROM [GOAT].[dbo].[GOAT1]
OPEN Goatcurse
FETCH NEXT FROM Goatcurse
INTO @Goatkey1, @Goatkey2
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Goat =
CASE
WHEN @Goatkey1 = 'Yes'
THEN @Goat+1
WHEN @Goatkey2 = 'Goat'
THEN @Goat+3
END;
UPDATE [GOAT].[dbo].[GOAT1]
SET Goatsight = @Goat
WHERE CURRENT OF Goatcurse
SET @Goat = 0
END
CLOSE Goatcurse
DEALLOCATE Goatcurse
下表为[GOAT].[dbo].[GOAT1]。对不起,我不知道如何像我在其他问题中看到的那样很好地格式化它
GOAT? GOATSE _Index Goatsight
Yes GOAT 1 NULL
Yes GOAT 2 NULL
No NULL 3 NULL
No NULL 4 NULL
Yes GOAT 5 NULL
Yes GOAT 6 NULL
Yes GOAT 7 NULL
No NULL 8 NULL
No NULL 9 NULL
Yes GOAT 10 NULL
上面的测试查询只是无限期地运行,没有任何Goatsight列条目被更新
我说的对吗
这对SQL来说是明智的做法吗?我不知道如何才能以一种可以在报告中使用的方式执行这种类型的计算
如果我的测试查询的命名方案太愚蠢/难以遵循,我也很抱歉,如果需要,我将重新编写
编辑:我测试了游标的行为,将while循环替换为
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT Goatsight
FROM [GOAT].[dbo].[GOAT1]
UPDATE [GOAT].[dbo].[GOAT1]
SET Goatsight = 6
WHERE CURRENT OF Goatcurse
FETCH NEXT FROM Goatcurse
INTO @Goatkey1, @Goatkey2
END
这将Goatsight列按顺序更新为6,因此我知道是while循环的内容被破坏了
我转而使用一系列包含在总和中的IIF函数来计算每行的Goatsight
OPEN Goatcurse
FETCH NEXT FROM Goatcurse
INTO @Goatkey1, @Goatkey2
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT Goatsight
FROM [GOAT].[dbo].[GOAT1]
SET @GoatSUM = SUM(IIF(@Goatkey1 = 'Yes',1,0)+
IIF(@Goatkey2 = 'GOAT',1,0))
UPDATE [GOAT].[dbo].[GOAT1]
SET Goatsight = @GoatSUM
WHERE CURRENT OF Goatcurse
SET @GoatSUM = 0
FETCH NEXT FROM Goatcurse
INTO @Goatkey1, @Goatkey2
END
然而,当我期望IIF函数根据上面的[GOAT1]表获得1的真实输出时,IIF函数的计算结果为0的假输出。As@Goatkey1应对应于[Goat?]列,@Goatkey2应对应于[Goatse]列
所以至少我知道问题出在哪里
编辑2:我在使用IF@Goatkey1='Yes'SET@Goat=@Goat+1时遇到了类似的问题,否则SET@Goat=@Goat+10
IF条件的计算结果不是true,而是获取ELSE输出
编辑3:它正在工作。我需要为varchar变量@Goatkey1和@Goatkey2设置一个长度。他们只读取了第一个字符,这当然会使我的IIF函数中设置的条件失效
我真是个白痴
谢谢你的帮助,杰迪
我相信这个问题可以解决。如果我知道..你的光标将永远运行,我会自己做这件事,因为你在WHILE块的末尾缺少了一个从goatCourse到@Goatkey1、@Goatkey2的FETCH NEXT,以迫使它移动到下一个记录,因此它将在第一行继续工作,直到你结束进程。非常感谢!在进行更改后,查询可以运行到完成,但是goatsight列仍然不会按照CASE块中指定的增量进行更新。我甚至不确定CASE块是否满足我的要求,因为我想要控制流,如果这对所有WHEN块都有意义的话,在@goat中给出一个总分,而不需要CASE语句在第一个WHEN块满足时中断一次。如果你想要两个CASE都触发,那么不要使用CASE,只使用if块。。。如果@GOATKEY1='YES'设置@GOAT=@GOAT+1如果@GOATKEY2='GOAT'设置@GOAT=@GOAT+3。。。只需确保在光标的下一次迭代之前将@GOAT设置为0。