Как я могу избежать использования курсора для реализации этого псевдокода - SQL Server - PullRequest
0 голосов
/ 18 марта 2011
CREATE PROCEDURE p_processDataFor @accountId
BEGIN

    for each item in 
      (select * from Accounts where accountId   = @accountId and isProcessed = 0)
    BEGIN
        CASE current row
            WHEN  has x Condition THEN
                exec p_x <Pass all data of current row>
            WHEN  has y Condition THEN
                exec p_y <Pass all data of current row>
            WHEN  has z Condition THEN
                exec p_z <Pass all data of current row>
            END
    END

END

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

Обычно вы не можете избежать зацикливания, так как вы вызываете EXEC, что не может быть выполнено как операция на основе SET; это должно быть сделано один за другим.

Если вы просто хотите избежать CURSOR в целом, вы можете реализовать его с помощью цикла WHILE.

В противном случае другой вариант заключается в использовании оператора SELECT + FOR XML, который строит операторы EXEC как один оператор NVARCHAR (MAX) в переменную, а затем EXEC только в этом динамическом SQL.

1 голос
/ 18 марта 2011

Хорошо, этот пример выполняет вставку только для условия X, но, надеюсь, покажет, как вы могли бы продолжить:

create table T1 (
    ID int IDENTITY(1,1) not null,
    Val1 varchar(10) not null,
    constraint PK_T1 PRIMARY KEY (ID)
)
go
create table T2 (
    ID int not null,
    Val2 varchar(10) not null,
    constraint PK_T2 PRIMARY KEY (ID)
)
go
create table Val (
    ID int IDENTITY(1,1) not null,
    Val1 varchar(10) not null,
    Val2 varchar(10) not null,
    Processed bit not null,
    CondX bit not null
)
go

Val - это моя таблица, содержащая строки, с которыми нужно работать (в вашем примере, Accounts).T1 и T2 - это две таблицы, которые в настоящее время вставляются / обновляются вашей p_x процедурой.

insert into Val(Val1,Val2,Processed,CondX)
select 'abc','def',0,1 union all
select 'ghi','jkl',0,0 union all
select 'mno','pqr',0,1
go

Просто некоторые примеры данных - у меня есть 3 строки, 2 из которых соответствуют «условию x»:

declare @Inter table (ValID int,T1ID int,Val2 varchar(10))

;merge into T1 using (select * from Val where CondX=1) Val on 1=0
when not matched then insert (Val1) values (Val.Val1)
output inserted.ID,Val.ID,Val.Val2 into @Inter (T1ID,ValID,Val2);

insert into T2(ID,Val2)
select T1ID,Val2 from @Inter

update Val set Processed = 1 where ID in (select ValID from @Inter)
go

Для вашей реальной работы вам понадобится 3 копии вышеупомянутых - по одной для каждого из x, y и z.Если он находится внутри одного и того же хранимого процесса, вам нужно использовать другое имя для таблицы @Inter. оператор слияния подвергается небольшому злоупотреблению, поскольку вы не можете использовать предложение OUTPUT , которое ссылается на другие таблицы из оператора вставки.Но мы используем это для того, чтобы получить сгенерированные значения IDENTITY из T1 вместе с соответствующими данными, которые будут вставлены в другие таблицы.

Так что теперь мы будем использовать переменную таблицы @Inter длядальнейшая вставка в T2, и в конечном итоге обновить Val, чтобы указать, что строки были обработаны.Если есть цепочка таблиц, в которую нужно вставить и получить значения идентификаторов, вам нужно будет ввести больше операторов слияния и табличных переменных.

select * from Val
select * from T1
select * from T2

И мы получим наши результаты:

ID          Val1       Val2       Processed CondX
----------- ---------- ---------- --------- -----
1           abc        def        1         1
2           ghi        jkl        0         0
3           mno        pqr        1         1

(3 row(s) affected)

ID          Val1
----------- ----------
1           abc
2           mno

(2 row(s) affected)

ID          Val2
----------- ----------
1           def
2           pqr

(2 row(s) affected)

Итак, мы выполнили всю нашу работу для условия X, сохраняя кодовый набор повсеместно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...