Вы не можете поместить не константную строку в предложение IN
предложения о свопинге. Вы можете использовать Pivot XML для этого.
Из documentation :
ПодпрограммаПодзапрос используется только в сочетании с ключевым словом XML. Когда вы указываете подзапрос, все значения, найденные подзапросом, используются для поворота
blockquote>. Он должен выглядеть следующим образом:
select xmlserialize(content t.B_XML) from t_aa pivot xml( sum(A) for B in(any) ) t;
Вместо этого также может быть подзапрос ключевого слова
ANY
:select xmlserialize(content t.B_XML) from t_aa pivot xml( sum(A) for B in (select cl from t_bb) ) t;
Судя по вашему нечетному / четному решению, похоже, не имеет значения, в какой последовательности обрабатываются запросы. Так что, может быть, ты мог бы сделать что-то подобное.
SELECT id, requestor, status, created, queuetime
FROM requests
WHERE status = 1
AND ID % 3 + 1 = 2
ORDER BY queuetime
Цифра 3 во втором условии представляет количество процессов. Цифра 2 указывает на второй процесс.
Похоже, вы хотите, чтобы 2+ процессора принимали записи из таблицы запросов
.
Можете ли вы добавить столбец в таблицу запросов
, чтобы указать, что он был обработан? Другими словами, вы захотите отслеживать, было ли оно «принято» и «закончено». Возможно, в этом случае закончено, может быть, вы удаляете записи из таблицы.
Поэтому рассмотрите возможность простого добавления столбца типа ProcessingOn DATETIME
.
С помощью этой конструкции вы можете затем иметь каждый процессор SELECT
его пакет, но, конечно, гарантируя, что он не принимает ни одного, уже находящегося в процессе обработки.
BEGIN TRAN
DECLARE @RecordsToProcess TABLE (ID int)
--grab our candidates
INSERT INTO @RecordsToProcess (ID)
SELECT ID FROM requests WHERE status = 1
AND ProcessingOn IS NULL ORDER BY queuetime
--mark our batch of records as 'in-process'.
UPDATE requests SET ProcessingOn = CURRENT_TIMESTAMP
WHERE ID IN (SELECT ID FROM @RecordsToProcess)
--get all those records to process.
SELECT * FROM requests
WHERE ID IN (SELECT ID FROM @RecordsToProcess)
COMMIT TRAN
Затем вы, вероятно, столкнетесь с ситуацией, когда партия не удалась. В этом случае записи никогда не удаляются, но их ProcessingOn
не равно нулю. Возможно, установите допуск повторных попыток в SELECT
, при этом порог (возможно, 5 минут, возможно, 1 день, в зависимости от того, что вам нужно) используется для определения необходимости повторной обработки этих записей.
--grab our candidates
INSERT INTO @RecordsToProcess (ID)
SELECT ID FROM requests WHERE status = 1
AND (ProcessingOn IS NULL OR ProcessingOn < DATEADD(day, -1, ProcessingOn)
ORDER BY queuetime