SQL Server: проблема обновления курсора - PullRequest
0 голосов
/ 10 мая 2018

У меня есть пользовательская функция для разделения строки:

 CREATE FUNCTION [dbo].[SplitString] 
 (
     @str NVARCHAR(MAX), 
     @separator CHAR(1)
 )
 RETURNS TABLE 
 AS
 return (
 with tokens(p, a, b) AS (
     select 
         cast(1 as bigint), 
         cast(1 as bigint), 
         charindex(@separator, @str)
     union all
     select
         p + 1, 
         b + 1, 
         charindex(@separator, @str, b + 1)
     from tokens
     where b > 0
 )
 select
     p-1 ItemIndex,
     substring(
         @str, 
         a, 
         case when b > 0 then b-a ELSE LEN(@str) end) 
     AS Item
 from tokens
 );

(кредит на этот код достается кому-то другому в Stack Overflow, которого я не могу вспомнить)

Это отлично работаетв другом сценарии я использую то же самое.

В конечном итоге это составляет часть ETL, с целью принятия этого:

ID | Title
1  | Mrs K

Into This:

ClientContactRef | Title | Forename
1                | Mrs   | K

Мой код выглядит следующим образом:

DECLARE @Title varchar(max)
DECLARE @ThirdPartyRef int

DECLARE cur CURSOR FOR
SELECT Title, ID FROM [Abacus].[dbo].[ThirdParty]
WHERE Title IS NOT NULL

OPEN cur

WHILE @@FETCH_STATUS = 0
    BEGIN
FETCH NEXT FROM cur INTO @Title, @ThirdPartyRef

UPDATE Migrate.ClientContact
SET Title = LEFT(Item,60)
FROM SplitString(@Title,CHAR(32))
WHERE ItemIndex = 0
AND Migrate.ClientContact.ClientContactRef = @ThirdPartyRef

UPDATE Migrate.ClientContact
SET Forename = LEFT(Item,60)
FROM SplitString(@Title,CHAR(32))
WHERE ItemIndex = 1
AND Migrate.ClientContact.ClientContactRef = @ThirdPartyRef

END

CLOSE Cur
Deallocate Cur

GO

Как уже упоминалось, я использую это в другом месте, чтобы разделить адрес на 5 компонентов (что мне также нужно сделать здесь), но я получаю ту же проблему - а именночто внутри курсора нет выходных данных из разделенной строки, поэтому все мои целевые поля заканчиваются нулем.

Функция splitstring работает вне курсора в одной строке, как и ожидалось, но один развнутри курсора ничего не возвращается.Я попытался поместить временную таблицу внутри курсора, чтобы поймать вывод splitstring, а там не было.

Заранее спасибо

Simon

1 Ответ

0 голосов
/ 10 мая 2018

Это должно достичь того, что вы пытаетесь сделать, одним оператором обновления и без курсора.

UPDATE MCC SET 
    MCC.Title = CASE WHEN SST.ItemIndex = 0 THEN LEFT(SST.Item,60) ELSE MCC.Title END
    ,MCC.ForeName = CASE WHEN SST.ItemIndex = 1 THEN LEFT(SST.Item,60) ELSE MCC.ForeName END
FROM Migrate.ClientContact AS MCC
    JOIN Abacus.dbo.ThirdParty AS ATP
        ON MCC.ClientContactRef = ATP.ID
    CROSS APPLY SplitString(ATP.Title,CHAR(32)) AS SST
WHERE SST.ItemIndex IN (0,1)
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...