web-dev-qa-db-ja.com

カーソルは止まりません

このカーソルでエラーが発生したようですが、自分が間違ったことを理解できていないようです。

selectが2行戻ることを確認しました。しかし、それをカーソルに渡してピックすると、文字列が表示され、必要な正確な値を抽出できます。 2つの行は次のようになります...

|DATAIDONTWANT|...|DATAIDONTWANT|<|1|DATAIDONTWANT|<|2|DATAIDONTWANT|...|
|DATAIDONTWANT|...|DATAIDONTWANT|<|1|DATAIDONTWANT|<|2|DATAIDONTWANT|...|

カーソルは最初の行をつかんでいるように見え、次の行に到達したりプログラムを終了したりせずにループし続けます。

declare
    @clobstringP varchar(max),
    @clobstring  varchar(max);

declare SevenCursor cursor for 
    select [value] as ClobP
    from string_split(@clobstring, '>')
    where value like '%<|2|%';

open SevenCursor;
fetch next from SevenCursor into @clobstringP;

while @@FETCH_STATUS = 0
begin
    insert into [database].dbo.tablestuff ( ValueP ) 
    select file387
    from ( 
        select 
             RowId387 = row_number() over( order by ( select 1 ) )
            ,file387  = [value]
        from string_split(@clobstringP, '|')
    ) a
    where a.RowId387 = 6;

end;

close SevenCursor;
deallocate SevenCursor;

誰かが私を正しい方向に向けることができますか?

1
TuckRollworthy

Peterが指摘したように、ループ内でフェッチを行わないため、ループが終了することはありません。 2つではなく、1つだけのFETCHを維持することを好みます。したがって、カーソルのループ構造は次のようになります。

WHILE 1 = 1
BEGIN
  FETCH NEXT FROM OrdersCursor INTO @sales_person_id, @orderdate;
    IF @@FETCH_STATUS <> 0
      BREAK

  --Whatever it is I'm doing inside the loop
END

あなたが好む味の問題...

0
Tibor Karaszi

@@fetchstatus = 0でない限り、カーソルは無限にループします。その状態に到達するには、データセットを処理する必要があります。これを行うには、fetch next from SevenCursor into @clobstringP;ブロックのinsidebegin ... endを追加して、カーソルが繰り返し処理できるようにする必要があります。


この段階で少し編集してカーソルを完全に捨てることをお勧めするのはおそらく賢明でしょう。カーソルはかなり気の利いたものですが、よく誤用されます。あなたが提供した疑似コードから、おそらくあなたは X にバイパスできるときにYを修正しようとしているようです。

whole結果セットを取得して string_split -を適切な#temp_tableに変換することをお勧めします。このキャッシュされた結果セットに対して必要な更新/削除を実行し、それが適切であることを確認したら、singleinsert into dbo.tablestuff ...がバッチ評価ルールに基づいて成功または失敗するかどうかを試します。例えば:

declare @pipe_delimited_rows table ( 
    my_row varchar(max)
);
insert @pipe_delimited_rows ( my_row ) 
values 
(N'|DATAIDONTWANT|...|DATAIDONTWANT|<|1|DATAIDONTWANT|<|2|DATAIDONTWANT|...|'),
(N'|DATAIDONTWANT|...|DATAIDONTWANT|<|1|DATAIDONTWANT|<|2|DATAIDONTWANT|...|');

drop table if exists #cache_results; 
create table #cache_results ( 
     id int identity not null primary key
    ,ClobP nvarchar(max)
); 

insert #cache_results ( ClobP )
select ss.[value] as ClobP
from @pipe_delimited_rows pdr
cross apply string_split(pdr.my_row, '>') ss -- delimiting appropriately here, of course
where ss.[value] like '%<|2|%';

/* perform business logic to validate interim results here */

insert into [database].dbo.tablestuff ( ValueP ) 
select ClobP
from #cache_results;

免責事項

5
Peter Vandivier