我在ms sql server 2008的循环中编写了一个存储过程,就像这样
BEGIN TRANSACTION
WHILE(@first <= @last)
BEGIN
Select @LineOfAuthorityNameSubString = TempLineOfAuthority from #tbTempLineOfAuthority;
Select @tbLineOfAuthorityId = LineOfAuthority
from tbLineOfAuthority where LineOfAuthorityX = @LineOfAuthorityNameSubString;
INSERT INTO tbProductLineOfAuthority(ProductId, LineOfAuthortyId)
VALUES(@tbProductId, @tbLineOfAuthorityId);
SET @first += @step
END
COMMIT TRANSACTION
现在问题在于这行代码
Select @tbLineOfAuthorityId = LineOfAuthority
from tbLineOfAuthority where LineOfAuthorityX = @LineOfAuthorityNameSubString;
变量@tbLineOfAuthorityId在循环中始终获得相同的值。 请帮帮我!!!
答案 0 :(得分:1)
你一直在@tbLineOfAuthorityId
获得相同值的原因是因为你的循环中第一个选择内部没有任何变化,这意味着你总是会在@tbLineOfAuthorityId
变量中得到相同的结果循环运行的时间。
正如其他人在评论部分中所述,除非您要求使用未提及的@first
,@last
和@step
,否则您的整个代码代码段可以替换为单个insert语句:
insert into tbProductLineOfAuthority
( ProductId,
LineOfAuthortyId )
select @tbProductId,
loa.LineOfAuthority
from tbLineOfAuthority loa
join
#tbTempLineOfAuthority tla on tla.TempLineOfAuthority = loa.LineOfAuthorityX
该语句将根据需要插入所有值(根据当前问题并假设对@step
的使用没有其他意义。
答案 1 :(得分:0)
如果要使用循环从表中获取数据,请使用CURSOR
。
我稍后会详细解释,但首先要考虑,
大多数基于光标的方法可以使用集合更有效地重写。
如果你可以使用SELECT
和INSERT
编写基于集合的查询,这很可能是一个更好的选择。
有关针对特定问题的基于集合的方法的示例,请参阅Bernd Linde's answer。对所述问题的规范回答如下。
如果你确实需要CURSOR
,这里有一些指导原则,
由于您将以只读方式使用数据并从头到尾进行扫描,因此您可以在定义中明确说明。由于光标将为READ ONLY
而FORWARD_ONLY
使用FAST_FORWARD
参数,因此这会对性能产生重大影响。
游标仅用于此批处理,因此应使用LOCAL
参数声明。
代码看起来应该是这样的
-- Declare the cursor.
DECLARE [someName] CURSOR LOCAL
FAST FORWARD
FOR
SELECT
[Some],
[Other]
FROM
[SomeTable];
OPEN [someName];
BEGIN TRY
-- Declare variables for storing the row.
DECLARE @some INT;
DECLARE @other NVARCHAR(MAX);
-- Get the first row
FETCH NEXT FROM [someName] INT @some, @other;
-- Loop through all the rows
WHILE @@FTECH_STATUS = 0 BEGIN
-- Do something useful with @some and @other
-- Get the next row.
FETCH NEXT FROM [someName] INT @some, @other;
END
END TRY
BEGIN CATCH
-- Error Handling
END CATCH
-- Always close and de-allocate the cursor, once it is opened.
CLOSE [someName];
DEALLOCATE [someName];