如何解决在TSQL过程中使用输出参数,然后在游标中调用该过程以更新表?
我尝试过更改程序中的表;但是,鉴于该表是在之后创建或删除的,所以这行不通吗?
在此之前,我尝试创建表,然后将过程中的值插入表中。失败了甚至没有运行。
无论我做什么,(表值)tvWin始终为空...
目标是创建一个石头剪刀布游戏,并使用游标遍历值表“ Rock / paper / scissors”。我想那部分很容易。
我只得到tvWin的空值。我猜这意味着在转移过程以更新表值时遇到问题。
这似乎非常令人费解,但这就是我应该做的。在过程中创建变量,创建要运行的代码;在过程外部创建空变量以存储游标的迭代值;然后,从游标中的过程中调用值。我的意思是,这开始像Inception。
工作光标代码:
使用scratch_DB;
DROP TABLE IF EXISTS tblRPS_data;
GO
-----
CREATE TABLE tblRPS_data
(
tvSeq INT IDENTITY PRIMARY KEY,tvP1 CHAR(1),tvP2 CHAR(1),tvWin CHAR(1)
);
GO
-----
INSERT INTO tblRPS_data(tvP1,tvP2)
VALUES ( 'R','R' ),( 'R','P' ),'S' ),( 'P',( 'S','S' );
DECLARE @lvSeq CHAR(1),@lvP1 CHAR(1),@lvP2 CHAR(1),@lvWin CHAR(1);
IF CURSOR_STATUS('global','csrMyCursor')>=-1
BEGIN
DEALLOCATE csrMyCursor;
END
DECLARE csrMyCursor CURSOR
FOR
SELECT tvSeq,tvP1,tvP2
FROM tblRPS_data;
OPEN csrMyCursor;
FETCH NEXT FROM csrMyCursor
INTO @lvSeq,@lvP1,@lvP2;
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF @lvP1 NOT IN ('R','P','S') OR @lvP1 NOT IN ('R','S')
SET @lvWin = 0;
ELSE IF @lvP1 + @lvP2 IN ('RS','PR','SP')
SET @lvWin = 1;
ELSE IF @lvP1 = @lvP2
SET @lvWin=3;
ELSE
SET @lvWin = 2;
IF @lvWin = 3
PRINT 'It is a tie'
ELSE
PRINT 'The Winner is Player ' + @lvWin;
UPDATE tblRPS_data
SET tvWin = @lvWin
WHERE tvSeq=@lvSeq;
FETCH NEXT FROM csrMyCursor
INTO @lvSeq,@lvP2;
END
CLOSE csrMyCursor;
DEALLOCATE csrMyCursor;
SELECT *
FROM tblRPS_data;
输出很好。
现在,如何将这个过程放在光标中而不是直接代码中?
USE scratch_DB;
GO
CREATE OR ALTER PROCEDURE udpCalcWinner( @parmP1 AS CHAR(1),@parmP2 AS CHAR(1) ) --creates procedure (program) with 2 inputs
AS
BEGIN
DECLARE @lvP1 AS CHAR(1),@lvP2 AS CHAR(1),@lvWin AS TINYINT;
IF @lvP1 NOT IN ('R','SP')
SET @lvWin = 1;
ELSE IF @lvP1 = @lvP2
SET @lvWin=3;
ELSE
SET @lvWin = 2;
RETURN 0;
END;
DROP TABLE IF EXISTS tblRPS_data;
CREATE TABLE tblRPS_data
(
tvSeq INT IDENTITY PRIMARY KEY,tvP2)
VALUES ( 'R','S' );
DECLARE @lvSeq AS INT,@lvP1 AS CHAR(1),@lvWin AS CHAR(1);
IF CURSOR_STATUS('global',@lvP2;
WHILE (@@FETCH_STATUS = 0)
-------------------------------------------
BEGIN
DECLARE @lvI AS INT;
EXECUTE @lvI = udpCalcWinner '@lvP1','@lvP2';
UPDATE tblRPS_data
SET tvWin = @lvWin
WHERE tvSeq = @lvSeq;
FETCH NEXT FROM csrMyCursor
INTO @lvSeq,@lvP2;
END;
CLOSE csrMyCursor;
DEALLOCATE csrMyCursor;
SELECT *
FROM tblRPS_data;
结果应该是9行;并且,tvWin列中的所有Null值都与游标代码不同。
解决方法
create procedure udpCalcWinner @lvP1 char(1),@lvP2 char(1),@lvWin char(1) output
.......
select @lvP1 = isnull(@lvP1,'-'),@lvP2 = isnull(@lvP2,'-') --handle null input
IF @lvP1 NOT IN ('R','P','S') OR @lvP2 NOT IN ('R','S')
SET @lvWin = '0'; --@lvWin is char...quotes ''
..............................................................
else if @lvWin = '0'
print 'invalid input'
ELSE
PRINT 'The Winner is Player ' + @lvWin;
GO
.........cursor loop .........
EXECUTE udpCalcWinner @lvP1 = @lvP1,@lvP2=@lvP2,@lvWin = @lvWin output;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。