如何使用while循环从表中获取数据?

时间:2014-11-06 08:57:38

标签: sql sql-server sql-server-2008

我在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在循环中始终获得相同的值。 请帮帮我!!!

2 个答案:

答案 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

我稍后会详细解释,但首先要考虑,

  

大多数基于光标的方法可以使用集合更有效地重写。

如果你可以使用SELECTINSERT编写基于集合的查询,这很可能是一个更好的选择。

有关针对特定问题的基于集合的方法的示例,请参阅Bernd Linde's answer。对所述问题的规范回答如下。


如果你确实需要CURSOR,这里有一些指导原则,

由于您将以只读方式使用数据并从头到尾进行扫描,因此您可以在定义中明确说明。由于光标将为READ ONLYFORWARD_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];