在while循环中执行SP仅适用于第一次

时间:2013-10-31 20:59:15

标签: sql-server

在SQL Server 2012中,我有一个多次调用存储过程的脚本。循环将执行[ResultHeader]表中记录数的次数。

 EXEC [AS400].tp_SelectChildItems @Pgm, @Grp, @Pgmgrpseq, 
                       null, null, null, null, null, @ItemSelection, null,
                       null, null, null, null, 

注意:此SP内部有table variable

我有一个以逗号分隔的SelectedCostPageList列表。对于此列表中的每个值,循环执行一次。

我正在观察一种奇怪的行为。当我从脚本调用sp时,只有sp第一次返回正确的记录。在后续调用中,存储过程不返回任何记录。很奇怪…。当我改变逗号分隔字符串的顺序时,仅对于第一次迭代,sp正在撤销记录..其他时候没有记录。

猜猜是什么原因?

       DECLARE @SelectedCostPageList VARCHAR(MAX)

       SET @SelectedCostPageList = (SELECT (SELECT CONVERT(VARCHAR(32), A.PGM + '-'+A.GRP+'-'+A.PGMGRPSEQ) + ', ' AS [text()]
       FROM dbo.[ResultHeader] A
       WHERE UserId = 'U25703'
       FOR XML PATH('')) AS CostPages) ResultHeader

       PRINT @SelectedCostPageList


       DECLARE @pos INT
       DECLARE @len INT
       set @pos = 0
       set @len = 0

              DELETE FROM ResultItems

       WHILE CHARINDEX(',', @SelectedCostPageList, @pos+1)>0
       BEGIN

              set @len = CHARINDEX(',', @SelectedCostPageList, @pos+1) - @pos
              DECLARE @SelectedCostPage VARCHAR(10)
              set @SelectedCostPage = SUBSTRING(@SelectedCostPageList, @pos, @len)
              set @pos = CHARINDEX(',', @SelectedCostPageList, @pos+@len) +1
              PRINT @SelectedCostPage



              DECLARE @Pgm AS VARCHAR (10);
              DECLARE @Grp AS VARCHAR (10);
              DECLARE @Pgmgrpseq AS VARCHAR (10);



              SELECT @Pgm = (SELECT VALUE
              FROM [AS400].[tf_SelectSplitString] (@SelectedCostPage, '-')
              WHERE POSITION = 1);
              PRINT @Pgm
              SELECT @Grp = (SELECT VALUE
              FROM [AS400].[tf_SelectSplitString] (@SelectedCostPage, '-')
              WHERE POSITION = 2);
              PRINT @Grp
              SELECT @Pgmgrpseq = (SELECT VALUE
              FROM [AS400].[tf_SelectSplitString] (@SelectedCostPage, '-')
              WHERE POSITION = 3);
              PRINT @Pgmgrpseq

              Declare @ItemSelection as varchar(4000)
              set @ItemSelection ='1116102540,1116102541';
              print @ItemSelection

              print 'HAI'
              print @Pgmgrpseq

                           EXEC [AS400].tp_SelectChildItems
                           @Pgm, @Grp, @Pgmgrpseq, 
                           null, null, null, 
                           null, null, @ItemSelection, null,
                           null, null, null, null, 
                           null, null, null, 1, 'U25703'



                           END

                           SELECT * FROM ResultItems
                           WHERE UserId = 'U25703'

1 个答案:

答案 0 :(得分:2)

如果我不得不猜测,那将是因为您使用', '(逗号后跟空格)作为列表分隔符,但代码只是寻找逗号。然后,您将在字符串值上有一个前导空格,这可能不会匹配任何需要匹配的内容。

第一个可行,因为您使用逗号初始化列表字符串而没有空格。

也许更重要的是,我发现把东西塞进一个字符串中的方法可以绕过它们,我要说的是,20世纪80年代。您可以使用游标(不是我最喜欢的方法)或临时表。当我想对这些数据做循环时,我有时会按如下方式构造它们:

declare @looptable table (rownum int identity(1, 1), . . . );
insert into @looptable . . .;
declare @tot int;
select @tot = count(*) from @looptable;
declare @i int = 1;
while (@i <= tot)
begin
    -- something here with "where rownum = @i"
end;

将值填充到字符串中只是为了编写更多代码来解析它们的想法似乎浪费了编程工作。此外,由于将类型转换为字符格式以及for path xml处理'<''>'等字符的淫秽方式,这可能会导致问题。