在我的sql代码中,我已经声明了一个表(A)并从数据库表(B)向该表插入了一些行。然后我必须从A中取出那些插入的行并将其放入CURSOR中,在我执行FETCH NEXT
后,@@FETCH_STATUS
仍为-1
。但@@FETCH_STATUS
的预期值为0
。
我在问题下面放了一个简化的代码。
我能知道这段代码有什么问题吗?我是否可以使用声明的表来填充SQL中的CURSOR
,或者必须从数据库中创建的表填充游标。
// This is a code that goes inside a Stored Procedure.
AS
DECLARE A TABLE (.........)// A table has same fields in table B
DECLARE s INT
WHILE EXISTS ( SELECT * FROM B WHERE ......)
BEGIN
BEGIN TRAN
INSERT INTO A SELECT TOP 10 (....)FROM B WITH (UPDLOCK, HOLDLOCK) WHERE ....
SELECT s = count(*) from A // this returns some value which means inserting is working
DECLARE dataSet CURSOR FOR (SELECT..... FROM A)
OPEN dataSet
FETCH NEXT FROM dataSet INTO ...
WHILE @@FETCH_STATUS = 0 // coming value for this is -1
BEGIN
//Code goes here
FETCH NEXT FROM dataSet INTO ...
END
CLOSE dataSet
DEALLOCATE dataSet
DELETE FROM A
COMMIT TRAN
END
答案 0 :(得分:1)
由于表A上的未提交事务,表A可能已被锁定。所以对于你的数据集游标try-
select '' from A with (nolock) where ...
答案 1 :(得分:1)
我认为创建临时表然后将其声明为游标,而不是必须有现有表 像:
DECLARE cursor_name CURSOR FOR SELECT id INTO temp_table FROM user_id
答案 2 :(得分:1)
这是OP问题的可运行版本 - 但它没有表现出问题。这不是答案,所以CW,如果OP确实发布了一个实际的例子,我将删除它:
create table B (ID int not null,Val1 varchar(10) not null)
go
insert into B(ID,Val1) values (1,'abc'),(2,'ade')
go
create procedure DoStuff
AS
DECLARE @A TABLE (ID int not null,Val1 varchar(10) not null)
DECLARE @s INT
WHILE EXISTS ( SELECT * FROM B WHERE Val1 like 'a%')
BEGIN
BEGIN TRAN
INSERT INTO @A SELECT TOP 10 ID,Val1 FROM B WITH (UPDLOCK, HOLDLOCK) WHERE Val1 like 'a%'
SELECT @s = count(*) from @A
DECLARE dataSet CURSOR FOR (SELECT ID,Val1 FROM @A)
declare @ID int
declare @Val1 varchar(10)
OPEN dataSet
FETCH NEXT FROM dataSet INTO @ID,@Val1
WHILE @@FETCH_STATUS = 0
BEGIN
RAISERROR('%i: %s',10,1,@ID,@Val1) WITH NOWAIT
UPDATE B set Val1 = 'done' where ID = @ID
FETCH NEXT FROM dataSet INTO @ID,@Val1
END
CLOSE dataSet
DEALLOCATE dataSet
DELETE FROM @A
COMMIT TRAN
END
GO
EXEC DoStuff
GO
SELECT * from B
输出:
(2 row(s) affected)
(2 row(s) affected)
1: abc
(1 row(s) affected)
2: ade
(1 row(s) affected)
(2 row(s) affected)
(2 row(s) affected)
和表格B
:
ID Val1
1 done
2 done