Question

I appear to have made an error in this cursor and I can't seem to figure out what I have done wrong.

I've confirmed that the select pulls back 2 rows. But when I pass it into the cursor to pick appear the string and I can extract the exact value I need. The two rows look something like the following...

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

The cursor appears to grab the 1st row and continually loop around never getting onto the next row or end the program.

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;

Can someone point me in the right direction?

Was it helpful?

Solution

As Peter has pointed out, your loop will never end since you don't do a fetch inside the loop. I prefer to have only one FETCH to maintain instead of two. So, my loop structure for a cursor is as follows:

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

A matter of taste which you prefer...

OTHER TIPS

The cursor will loop infinitely unless and until @@fetchstatus = 0. In order to reach that state, you need to proceed through the dataset. In order to do that, you should add fetch next from SevenCursor into @clobstringP; to the inside of the begin ... end block so that the cursor has something to iterate over.


It is perhaps prudent to editorialize a bit at this stage and recommend that you try to ditch the cursor entirely. Cursors are pretty nifty but are misused more often than not; and from your provided psuedo-code, it seems that perhaps you may be trying to fix X when you could bypass to Y.

I might suggestion taking the whole result set and string_split-ing it into a sensible #temp_table. When you've performed any necessary updates/deletes on this cached result set and verified it's suitable, try for a single insert into dbo.tablestuff ... to succeed or fail based on batch evaluated rules. For example:

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;

Disclaimers

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top