Выполнение оператора печати для каждой строки в наборе результатов в значительной степени требует курсор или подход, аналогичный этому
declare @id int, @stuff varchar(20)
declare @tmp table
(
id int not null
, stuff varchar(20)
primary key(id)
)
insert @tmp
select id, stuff from mastertable
where condition1 > condition2
select top 1 @id=id, @stuff=stuff from @tmp
while (@@rowcount > 0)
begin
print @stuff
delete from @tmp where [email protected]
select top 1 @id=id, @stuff=stuff from @tmp
end
Вы по-прежнему перемещаетесь по каждой строке, но избегаете курсора. Поскольку вы используете таблицу var вместо курсора, вы избегаете блокировки таблицы, но это не обязательно лучший подход. Вы можете обрабатывать строки за строкой множеством возможных способов, таких как добавление «обработанного столбца» или нумерация всех выбранных строк 1..n и итерация в соответствии с номером rownumber
Вы можете избегать только перекрестной обработки, если вы можете выполнить операцию на основе набора. В вашем вопросе недостаточно информации о том, можно ли избежать этого в TSQL.
Теперь запись CLR-proc может быть более гибкой, так как у вас намного более богатая модель программирования, и для каждой строки результирующий набор в процедуре CLR. Выполнение вызова базы данных из процедуры CLR для каждой строки, вызываемой вызовом базы данных из каждой строки в TSQL
EDIT - Я вижу, что кто-то уже добавил один из возможных способов преобразования выводов печати в операцию, ориентированную на набор. то есть
declare @msg varchar(max)
select @msg = ''
select msg = @msg + stuff
from mastertable where condition1 > condition2
print @msg
Это нормально, на самом деле оптимально, о чем я говорил, когда говорил, что выполнял заданную операцию. Операция, основанная на наборе, всегда предпочтительнее, когда это возможно. Это может быть не очевидно, но конкатенация строк также может быть очень медленной в этом примере, если задействовано много строк.
Я сказал, что использование temp var позволяет избежать блокировки таблиц. Это не совсем так, поскольку SQL-сервер записывает temp vars в таблицу в tempdb. Я действительно имел в виду, что вы избегаете блокировки производственной таблицы, и, поскольку вы гарантированно являетесь единственным пользователем этой таблицы, вы не конкурируете за одновременный доступ.
Я также не пытался оптимизировать это. Например, внутренний цикл может отслеживать идентификатор, а условие where становится id> @id (вам также нужен первичный ключ, определенный на id). Поскольку временная таблица не обновляется во время каждой итерации цикла, я бы ожидал, что она будет быстрее.
Информация не достаточна.Чего вы на самом деле пытаетесь достичь? Если вы дадите нам полный сценарий, вы можете обнаружить, что существует полностью установленный способ делать то, что вам нужно. – gvee
Почему бы вам просто не добавить один дополнительный столбец идентификатора в «temp table», который вы уже создали, и цикл для каждой строки. –
Если вы просто хотите распечатать эту информацию «в конце», почему вам нужен курсор? – DrCopyPaste