T-SQL 存储过程中的游标
T-SQL Cursor in stored procedure
我正在使用存储过程并且我想使用游标来插入新数据(如果数据存在我想更新)
ALTER Procedure [dbo].[conn]
@ResellerID int,
@GWResellerID int,
@UserName varchar(50),
@Password varchar(50),
@URL varchar(100),
@ServiceType int,
@ServiceDesc varchar(50),
@FeedFrom bit,
@PublicKey varchar(max)
AS
declare gateway cursor for
select *
from reseller_profiles
where main_reseller_ID = @ResellerID
OPEN gateway
FETCH NEXT FROM gateway INTO @ResellerID
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO [dbo].tblGatewayConnection([ResellerID],[GWResellerID], [UserName], [Password], [URL], [ServiceType], [ServiceDesc],[feedFromMain], publicKey)
VALUES (@ResellerID, @GWResellerID, @UserName, @Password, @URL, @ServiceType, @ServiceDesc, @FeedFrom, @PublicKey)
FETCH NEXT FROM gateway INTO @ResellerID
END
CLOSE gateway
DEALLOCATE gateway
我的 table 名字是 tblGatewayConnection
有这些列:
resellerID
gwResellerID
userName
password
url
serviceType
serviceDesc
feedFromMain
publicKey
当我使用存储过程插入数据时,出现异常
Cursorfetch: The number of variables declared in the INTO list must match that of selected columns.
我错过了什么?
我们将不胜感激。
谢谢。
为什么还要用光标呢?!?!?!?!?我不会告诉您光标出了什么问题 - 因为与其修复光标,您应该首先学习避免它!
认真 - 避免 RBAR(逐行痛苦)尽可能处理,在这里,它真的毫无意义使用游标 - 只需使用这个干净整洁的 set-based 语句:
ALTER PROCEDURE [dbo].[conn] @ResellerID INT,
@GWResellerID INT,
@UserName VARCHAR(50),
@Password VARCHAR(50),
@URL VARCHAR(100),
@ServiceType INT,
@ServiceDesc VARCHAR(50),
@FeedFrom BIT,
@PublicKey VARCHAR(max)
AS
INSERT INTO dbo.tblGatewayConnection
(ResellerID, GWResellerID, UserName, Password,
URL, ServiceType, ServiceDesc, feedFromMain,
publicKey)
SELECT
ResellerID, GWResellerID, UserName, Password,
URL, ServiceType, ServiceDesc, feedFromMain,
publicKey
FROM
dbo.reseller_profiles
WHERE
main_reseller_ID = @ResellerID
大功告成!!没有凌乱的游标,没有不必要的局部变量 - 只是一个简单的 INSERT ... SELECT
,你已经实现了你想要的!
我不确定错误消息是否更容易解释:
Cursorfetch: The number of variables declared in the INTO list must match that of selected columns.
您正在 selecting 所有 来自 reseller_profiles
的列
declare gateway cursor for
select *
from reseller_profiles
where main_reseller_ID = @ResellerID
并尝试将它们放入单个变量中:
FETCH NEXT FROM gateway INTO @ResellerID
您 select 在光标中的列数必须与您要插入的变量数相匹配,因此您需要
declare gateway cursor for
select reseller_id
from reseller_profiles
where main_reseller_ID = @ResellerID
但是 你不应该为此使用游标,你可以使用相同的东西 INSERT .. SELECT
:
INSERT INTO [dbo].tblGatewayConnection
( [ResellerID],[GWResellerID], [UserName], [Password], [URL],
[ServiceType], [ServiceDesc],[feedFromMain], publicKey
)
SELECT Resellerid, @GWResellerID, @UserName, @Password,
@URL, @ServiceType, @ServiceDesc, @FeedFrom, @PublicKey
FROM reseller_profiles
WHERE main_reseller_ID = @ResellerID;
如前所述,您应该不惜一切代价避免游标,如果您绝对必须使用游标,请尽可能声明最轻量级的游标。例如,在您的情况下,您只是在游标内向前移动,只读取数据,不修改数据,并且只在本地访问游标,因此您可以按如下方式声明游标:
DECLARE gateway CURSOR LOCAL STATIC FAST_FORWARD
FOR
SELECT ...
FROM ..
虽然游标在最好的时候表现得非常糟糕,但懒惰的声明给它们带来了更糟糕的声誉。
我正在使用存储过程并且我想使用游标来插入新数据(如果数据存在我想更新)
ALTER Procedure [dbo].[conn]
@ResellerID int,
@GWResellerID int,
@UserName varchar(50),
@Password varchar(50),
@URL varchar(100),
@ServiceType int,
@ServiceDesc varchar(50),
@FeedFrom bit,
@PublicKey varchar(max)
AS
declare gateway cursor for
select *
from reseller_profiles
where main_reseller_ID = @ResellerID
OPEN gateway
FETCH NEXT FROM gateway INTO @ResellerID
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO [dbo].tblGatewayConnection([ResellerID],[GWResellerID], [UserName], [Password], [URL], [ServiceType], [ServiceDesc],[feedFromMain], publicKey)
VALUES (@ResellerID, @GWResellerID, @UserName, @Password, @URL, @ServiceType, @ServiceDesc, @FeedFrom, @PublicKey)
FETCH NEXT FROM gateway INTO @ResellerID
END
CLOSE gateway
DEALLOCATE gateway
我的 table 名字是 tblGatewayConnection
有这些列:
resellerID
gwResellerID
userName
password
url
serviceType
serviceDesc
feedFromMain
publicKey
当我使用存储过程插入数据时,出现异常
Cursorfetch: The number of variables declared in the INTO list must match that of selected columns.
我错过了什么?
我们将不胜感激。
谢谢。
为什么还要用光标呢?!?!?!?!?我不会告诉您光标出了什么问题 - 因为与其修复光标,您应该首先学习避免它!
认真 - 避免 RBAR(逐行痛苦)尽可能处理,在这里,它真的毫无意义使用游标 - 只需使用这个干净整洁的 set-based 语句:
ALTER PROCEDURE [dbo].[conn] @ResellerID INT,
@GWResellerID INT,
@UserName VARCHAR(50),
@Password VARCHAR(50),
@URL VARCHAR(100),
@ServiceType INT,
@ServiceDesc VARCHAR(50),
@FeedFrom BIT,
@PublicKey VARCHAR(max)
AS
INSERT INTO dbo.tblGatewayConnection
(ResellerID, GWResellerID, UserName, Password,
URL, ServiceType, ServiceDesc, feedFromMain,
publicKey)
SELECT
ResellerID, GWResellerID, UserName, Password,
URL, ServiceType, ServiceDesc, feedFromMain,
publicKey
FROM
dbo.reseller_profiles
WHERE
main_reseller_ID = @ResellerID
大功告成!!没有凌乱的游标,没有不必要的局部变量 - 只是一个简单的 INSERT ... SELECT
,你已经实现了你想要的!
我不确定错误消息是否更容易解释:
Cursorfetch: The number of variables declared in the INTO list must match that of selected columns.
您正在 selecting 所有 来自 reseller_profiles
declare gateway cursor for
select *
from reseller_profiles
where main_reseller_ID = @ResellerID
并尝试将它们放入单个变量中:
FETCH NEXT FROM gateway INTO @ResellerID
您 select 在光标中的列数必须与您要插入的变量数相匹配,因此您需要
declare gateway cursor for
select reseller_id
from reseller_profiles
where main_reseller_ID = @ResellerID
但是 你不应该为此使用游标,你可以使用相同的东西 INSERT .. SELECT
:
INSERT INTO [dbo].tblGatewayConnection
( [ResellerID],[GWResellerID], [UserName], [Password], [URL],
[ServiceType], [ServiceDesc],[feedFromMain], publicKey
)
SELECT Resellerid, @GWResellerID, @UserName, @Password,
@URL, @ServiceType, @ServiceDesc, @FeedFrom, @PublicKey
FROM reseller_profiles
WHERE main_reseller_ID = @ResellerID;
如前所述,您应该不惜一切代价避免游标,如果您绝对必须使用游标,请尽可能声明最轻量级的游标。例如,在您的情况下,您只是在游标内向前移动,只读取数据,不修改数据,并且只在本地访问游标,因此您可以按如下方式声明游标:
DECLARE gateway CURSOR LOCAL STATIC FAST_FORWARD
FOR
SELECT ...
FROM ..
虽然游标在最好的时候表现得非常糟糕,但懒惰的声明给它们带来了更糟糕的声誉。