我正在使用存储过程,我想使用游标来插入新数据(如果数据存在,我想更新)
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
我的表名tblGatewayConnection
包含以下列:
resellerID
gwResellerID
userName
password
url
serviceType
serviceDesc
feedFromMain
publicKey
当我使用存储过程插入数据时,我得到一个异常
Cursorfetch:INTO列表中声明的变量数必须与所选列的变量数相匹配。
我错过了什么?
任何帮助将不胜感激。
感谢。
答案 0 :(得分:6)
为什么甚至打扰光标?!?!?!?!?我不会告诉你光标有什么问题 - 因为你不应该固定光标,而应该首先学习以避免它!
严肃地说 - 避免 RBAR( row-by-agonizing-row )处理,只要你可以,这里使用游标真是完全没有意义 - 只需使用这个漂亮而干净的基于集合的语句:
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
,你已经实现了你想要的!
答案 1 :(得分:4)
我不确定错误消息是否可以更加自我解释:
Cursorfetch:INTO列表中声明的变量数必须与所选列的变量数相匹配。
您正在从reseller_profiles
declare gateway cursor for
select *
from reseller_profiles
where main_reseller_ID = @ResellerID
试图将它们放入一个变量中:
FETCH NEXT FROM gateway INTO @ResellerID
您在光标中选择的列数必须与要插入的变量数相匹配,因此您需要类似
的内容declare gateway cursor for
select reseller_id
from reseller_profiles
where main_reseller_ID = @ResellerID
HOWEVER 你不应该使用游标,你可以使用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 ..
尽管游标在最好的时候表现得非常糟糕,但是懒惰的声明给它们带来了更糟糕的声誉。