在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'
答案 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
处理'<'
和'>'
等字符的淫秽方式,这可能会导致问题。