虽然存储过程中的循环不起作用

时间:2013-01-14 10:44:49

标签: sql-server-2008 tsql stored-procedures while-loop

我正在研究数据库(学校项目)。我需要对该数据库进行一些测试(SQL Server 2008 R2)。

我试图测试它的恢复情况。我正在建立一个存储过程,以便花费足够长的时间来崩溃我的电脑。

问题在于我使用doenst的while循环似乎有效。

存储过程:

USE [OnderzoekSQL]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[Test_pro_opnemen] 
-- Add the parameters for the stored procedure here
@bnummer int OUT,
@i int

AS
BEGIN

SET NOCOUNT ON;
WHILE(@i <= @@ROWCOUNT )
    -- Insert statements for procedure here
    SELECT TOP 1 @bnummer = accountnumber
    FROM dbo.bank 
    ORDER BY saldo DESC

    PRINT @bnummer

    UPDATE bank
    SET saldo = '0'
    WHERE accountnumber = @bnummer
    SET @i = @i+1

END

表格:

CREATE TABLE [dbo].[bank](
[accountnumber] [nvarchar](50) NOT NULL,
[saldo] [real] NULL,
[owner_id] [int] NULL;

关于nvarchar和accountnumber的int之间的区别。它并不重要,因为我只使用帐号中的数字。

如果我删除While循环

,该过程将起作用

5 个答案:

答案 0 :(得分:1)

在第一个循环中,迭代@@Rowcount将为1 - 您可以在新的查询窗口中自行测试。

假设@i通常> gt = = 1,循环将在第一次迭代时退出。

答案 1 :(得分:1)

为什么要这样做

WHILE(@i <= @@ROWCOUNT )

@@ROWCOUNT返回受最后一个语句影响的行数。因此,UPDATE将该数字放入@@ROWCOUNT,然后增加@i。你想要达到的目标是什么?只要您的UPDATE更新的行数少于@i+1,您的WHILE循环就会终止。

答案 2 :(得分:0)

我同意其他所有人的意见,但我建议你以某种方式决定你的MAX条款,这可能会解决问题:

而不是返回受影响的最后一个语句行的@@ Rowcount,获取可以显式声明和保持的内容。我通常使用变量。要注意有时候复杂的循环可能需要三个变量开始结束,一个变量用于谓词。有时我发现你可能正在从一个语句中更新一个复杂的查询,比如开始日期,你需要将它与一个从一个集合中增加的变量分开。

以下是我将使用的循环方法的一个简单示例:

declare @Table Table ( personID int identity, person varchar(8));

insert into @Table values ('Brett'),('John'),('Peter');

-- say I want to affect a whole table.  I need to get it's count and HOLD it.  You could just select an expression but a variable is more clean IMHO.
declare @Max int;

-- I should set a beginning variable and statically set it, however if you are doing an update in the middle of something you can set it with 
-- a select expression as well.
declare @Current int = 1;

-- bind the variable to the count of a table I want to update.  My example is simple, it could work with a table that is very large as well though.
select @Max = count(*) from @Table

-- see data before loop
select * From @Table;

while @Current <= @Max  -- @Current is explicitly set and so is Max.  However @Current will increment in the BEGIN END BLOCK.
BEGIN
    update @Table set person = person + 'New' where personID = @Current -- update from @Current variable 

    set @Current += 1;  -- increment up one in the loop AFTER OPERATION
END

-- see data after the loop
select *
from @Table

答案 3 :(得分:0)

这可能是旧的,但在您原来的WHILE语句中,您只是在WHILE语句之后执行第一行代码。你必须在循环中有一个BEGIN和END。

你的循环应该是这样的:

WHILE(@i <= @@ROWCOUNT )

   BEGIN

    -- Insert statements for procedure here
       SELECT TOP 1 @bnummer = accountnumber
       FROM dbo.bank 
       ORDER BY saldo DESC

       PRINT @bnummer

       UPDATE bank
       SET saldo = '0'
       WHERE accountnumber = @bnummer
       SET @i = @i+1

   END

答案 4 :(得分:0)

尝试使用While循环....

SET NOCOUNT ON
 DECLARE @LoopCounter INT , @MaxEmployeeId INT, 
    @EmployeeName NVARCHAR(100)

SELECT @LoopCounter = min(id) , @MaxEmployeeId = max(Id) FROM #Employee

WHILE  ( @LoopCounter IS NOT NULL AND  @LoopCounter <= @MaxEmployeeId)

BEGIN
 UPDATE TOP(1) #Employee
 SET  Status = 1, @EmployeeName = Name WHERE Id = @LoopCounter  AND Status = 0 

PRINT @EmployeeName

   SELECT @LoopCounter  = min(id) FROM #Employee WHERE Id >= @LoopCounter AND Status = 0
END