Как можно перебрать результаты хранимой процедуры из другой хранимой процедуры ... без курсоров? - PullRequest
7 голосов
/ 29 сентября 2008

Я не уверен, что это то, что я должен делать в T-SQL или нет, и я почти уверен, что использование слова «итерация» было неверным в этом контексте, так как вы никогда не должны повторять что-либо в SQL. Это должна быть заданная операция, верно? Во всяком случае, вот сценарий:

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

Как мне это сделать без использования курсоров? Должно быть легким для вас sql гуру!

Ответы [ 7 ]

15 голосов
/ 29 сентября 2008

Это может быть не самым эффективным, но я бы создал временную таблицу для хранения результатов сохраненного процесса, а затем использовал бы ее в соединении с целевой таблицей. Например:

CREATE TABLE #t (uniqueid int)
INSERT INTO #t EXEC p_YourStoredProc

UPDATE TargetTable 
SET a.FlagColumn = 1
FROM TargetTable a JOIN #t b 
    ON a.uniqueid = b.uniqueid

DROP TABLE #t
2 голосов
/ 30 сентября 2008

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

CREATE FUNCTION dbo.udfGetUniqueIDs
()
RETURNS TABLE 
AS
RETURN 
(
    SELECT uniqueid FROM dbo.SomeWhere
)

GO

UPDATE dbo.TargetTable 
SET a.FlagColumn = 1
FROM dbo.TargetTable a INNER JOIN dbo.udfGetUniqueIDs() b 
    ON a.uniqueid = b.uniqueid

Edit: Это будет работать на SQL Server 2000 и выше ...

0 голосов
/ 29 сентября 2008

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

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

0 голосов
/ 29 сентября 2008

Вы можете использовать временную таблицу или переменную таблицы с дополнительным столбцом:

DECLARE @MyTable TABLE (
    Column1 uniqueidentifer,
    ...,
    Checked bit
)

INSERT INTO @MyTable
SELECT [...], 0 FROM MyTable WHERE [...]

DECLARE @Continue bit
SET @Continue = 1
WHILE (@Continue)
BEGIN
    SELECT @var1 = Column1,
           @var2 = Column2,
           ...
    FROM @MyTable
    WHERE Checked = 1

    IF @var1 IS NULL
        SET @Continue = 0
    ELSE
    BEGIN

        ...

        UPDATE @MyTable SET Checked = 1 WHERE Column1 = @var1
    END
END

Изменить: На самом деле, в вашей ситуации объединение будет лучше; приведенный выше код является итерацией без курсора, что является избыточным для вашей ситуации.

0 голосов
/ 29 сентября 2008

Используйте временные таблицы или переменную таблицы (вы используете SS2005).

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

0 голосов
/ 29 сентября 2008

Вставьте результаты сохраненного процесса во временную таблицу и присоедините ее к таблице, которую вы хотите обновить:

INSERT INTO #WorkTable
EXEC usp_WorkResults

UPDATE DataTable
  SET Flag = Whatever
FROM DataTable
INNER JOIN #WorkTable
  ON DataTable.Ket = #WorkTable.Key
0 голосов
/ 29 сентября 2008

Уродливое решение состоит в том, чтобы ваша процедура возвращала «следующий» идентификатор каждый раз, когда она вызывается, с использованием другой таблицы (или некоторого флага в существующей таблице) для фильтрации строк, которые она уже вернула

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