1

たまにしか発生しない奇妙な問題があります。私はそれを10000回実行しましたが、2回のエラー、12回のエラー、および異なる時間でのエラーは発生しませんでした。

これは、10000回試行してエラーのあるものを出力する私のテストスクリプトです

declare @i int
set @i = 10000

declare @v varchar(200)

while @i > 0
begin
    SELECT top 1 @v = val
    FROM f_split_string('a,b,c,d,e,f',',')
   if @v != 'a'
       print @v
   set @i = @i - 1
end

そして、ここにf_split_string関数があります:

CREATE FUNCTION [dbo].[f_split_string] (@s nvarchar(max), @delim nvarchar(10))
-- returns a table from a delimited string
-- Parameters:
--    @s                The delimited string
--    @delim            The delimiter characters
-- Example:
--    SELECT val FROM f_split_string('a b c',' ')
RETURNS @t TABLE (id int, val nvarchar(max))
AS
BEGIN
      DECLARE @c int, @v nvarchar(max)
      SET @c = 1
      SET @v = dbo.f_element(@s, @delim, @c)
      WHILE @v IS NOT NULL
      BEGIN
            INSERT INTO @t (id,val) VALUES (@c,@v)
            SET @c = @c + 1
            SET @v = dbo.f_element(@s, @delim, @c)
      END

      RETURN
END

そして、ここにf_element関数があります:

CREATE FUNCTION [dbo].[f_element](@Input varchar(max), @Delimiter varchar(10), @ElementNumber int)
-- returns an element from a delimited string
-- Example:
--   SELECT dbo.f_element('abc|def|ghij', '|', 2)
--     will return the 2nd element - def
RETURNS varchar(max)
AS
BEGIN
      DECLARE @Pointer INT, @Count INT, @Last INT, @retVal varchar(max)
      SET @Pointer = 1
      SET @Count = 1
      SET @Last = 1

      WHILE (@Count < @ElementNumber)
      BEGIN
            SET @Pointer = CHARINDEX(@Delimiter,@Input,@Pointer)
            IF @Pointer = 0
                  BREAK

            SET @Pointer = @Pointer + DATALENGTH(@Delimiter)
            SET @Count = @Count + 1
      END

      IF @Pointer = 0 OR @ElementNumber < 1
            SET @retVal = null;
      ELSE IF SUBSTRING(@Input,@Pointer,DATALENGTH(@Delimiter)) = @Delimiter
            SET @retVal = '';
      ELSE
      BEGIN
            SET @Last = @Pointer

            SET @Pointer = CHARINDEX(@Delimiter,@Input,@Last+1)

            IF @Pointer = 0
                  SET @retVal = SUBSTRING(@Input, @Last, 9999)
            ELSE
                  SET @retVal = SUBSTRING(@Input, @Last, @Pointer - @Last)
      END

      RETURN @retVal
END

これは SQL Server 2008 (R2 ではない) でテストされています。

第一に、他の誰かが私のテスト スクリプトでエラーを受け取ることはありますか? 第二に、なぜこれが起こっているのでしょうか?

f_element関数を問題なく200000回実行したので、f_split_string関数を疑いますが、f_split_stringから呼び出された場合はf_element関数である可能性があります

単一ユーザーの SQL Server 2008 R2 で問題なく実行しました。2008 には複数のユーザーがいます

誰でも私を助けることができます

エラーは、区切り文字列の間違った部分です。アタリのはずですが、たまに他のパーツです。行が間違った順序で一時テーブルに挿入されているかのようです。出力をソートできるように一時テーブルに id 列を追加しましたが、違いはありませんでした。

4

2 に答える 2