Son*_*ner 1 sql-server stored-procedures cursor
我正在使用存储过程,我想使用游标插入新数据(如果数据存在,我想更新)
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
Run Code Online (Sandbox Code Playgroud)
我的表名tblGatewayConnection
有以下列:
resellerID
gwResellerID
userName
password
url
serviceType
serviceDesc
feedFromMain
publicKey
Run Code Online (Sandbox Code Playgroud)
当我使用存储过程插入数据时,我得到一个例外
Cursorfetch:INTO列表中声明的变量数必须与所选列的变量数相匹配.
我错过了什么 ?
任何帮助将不胜感激.
谢谢.
为什么甚至打扰光标?!?!?!?!?我不会告诉你你的光标有什么问题 - 因为你不应该固定光标,而应该首先学会避免它!
说真的 - 尽可能避免使用 RBAR(逐行编排)处理,这里使用游标真是完全没有意义 - 只需使用这个漂亮而干净的基于集合的语句:
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
Run Code Online (Sandbox Code Playgroud)
你做完了!! 没有杂乱的光标,没有不必要的局部变量 - 只是一个简单的INSERT ... SELECT
你已经实现了你想要的!
我不确定错误消息是否可以自我解释:
Cursorfetch:在INTO列表中声明的变量数量必须与所选列的数量匹配。
您正在从中选择所有列reseller_profiles
declare gateway cursor for
select *
from reseller_profiles
where main_reseller_ID = @ResellerID
Run Code Online (Sandbox Code Playgroud)
并尝试将它们放入单个变量中:
FETCH NEXT FROM gateway INTO @ResellerID
Run Code Online (Sandbox Code Playgroud)
您在游标中选择的列数必须与您要插入的变量数相匹配,因此您需要
declare gateway cursor for
select reseller_id
from reseller_profiles
where main_reseller_ID = @ResellerID
Run Code Online (Sandbox Code Playgroud)
但是,您不应该为此使用游标,您可以使用相同的东西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;
Run Code Online (Sandbox Code Playgroud)
如前所述,您应该不惜一切代价避免使用游标,如果绝对必须使用游标,则可以声明最轻量的游标。以您的情况为例,您仅在游标内前进,仅读取数据,未修改数据,并且仅在本地访问游标,因此您将声明游标,如下所示:
DECLARE gateway CURSOR LOCAL STATIC FAST_FORWARD
FOR
SELECT ...
FROM ..
Run Code Online (Sandbox Code Playgroud)
尽管游标在最佳情况下表现出色,但懒惰的声明却给它们带来了更糟糕的声誉。
归档时间: |
|
查看次数: |
890 次 |
最近记录: |