Хранимая процедура SQL с несколькими циклами дескриптора вставки или несколькими значениями scope_insert - PullRequest
0 голосов
/ 11 января 2012

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

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

Ниже приведена структура моей таблицы:

CREATE TABLE QueueItem (
    QueueItemID [int] IDENTITY NOT NULL,
    ReferenceID [int] NOT NULL,
    StartDate [datetime] NOT NULL
);

CREATE TABLE CatalogDate (
    ReferenceID [int] NOT NULL,
    CatalogID [int] NOT NULL,
    DayCount [int] NOT NULL
);

CREATE TABLE ItemInterval (
    ReferenceID [int] NOT NULL,
    Interval [int] NOT NULL
);


CREATE PROCEDURE SetQueueItem
    @ReferenceID [int],
    @UserID [int]
AS
BEGIN

    DECLARE @DayCount [int]
    DECLARE @CatalogID [int]
    DECLARE @QueueItemID [int]

    SELECT @DayCount = DayCount, @CatalogID = CatalogID
    FROM CatalogDate
    WHERE ReferenceID = @ReferenceID

    DECLARE @Date [datetime] = --SELECT Date from another table using @UserID and @CatalogID

    DECLARE @StartDate [datetime] = (SELECT DATEADD(dd, @DayCount, @Date))

    INSERT INTO QueueItem(ReferenceID, StartDate)
    SELECT @ReferenceID, DATEADD(@DateCount-Interval), @Date)
    FROM ItemInterval
    WHERE ReferenceID = @ReferenceID --SELECT RETURNS MULTIPLE ROWS

Теперь, когда вставка нескольких записейсделано, мне нужно взять QueueItemID, сгенерированные из вставок, и вставить их вместе с некоторыми дополнительными данными в две другие таблицы.

Единственный способ добиться этого, который я вижу, состоит в том, чтобы либо разбить INSERT для циклического прохождения каждой записи в ItemInterval и вставлять их по одной за раз, либо запросить записи MAX из QueueItem таблица до и после вставки, а затем перебрать разницу, предполагая, что идентификаторы совершенно последовательны.

Мысли?

Ответы [ 2 ]

1 голос
/ 11 января 2012
0 голосов
/ 18 января 2012

Спасибо @ StarShip3000 за ссылки на OUTPUT

Чтобы решить эту проблему, я поместил результаты в таблицу переменных, используя OUTPUT, а затем с помощью этой таблицы вставил результаты в другие таблицы.

DECLARE @QueueItemTable TABLE
(
    ItemID [int]
)

INSERT QueueItem(ReferenceID, StartDate)
OUTPUT inserted.QueueItemID INTO @QueueItemTable(ItemID)
SELECT @ReferenceID, DATEADD(@DateCount-Interval), @Date)
FROM ItemInterval
WHERE ReferenceID = @ReferenceID --INSERTS IDENTITIES into @QueueItemTable variable

--Insert into other tables

INSERT QueueRelationship(QueueItemID)
SELECT ItemID
FROM @QueueItemTable

Viola!

...