Есть ли в SQL Server 2005 способ удалить строки и узнать, сколько на самом деле было удалено?
Я мог бы сделать select count(*) с такими же условиями, но мне нужно, чтобы это было абсолютно надежным.
Мое первое предположение состояло в том, чтобы использовать переменные @@ROWCOUNT, но это не установлено, например
delete
from mytable
where datefield = '5-Oct-2008'
select @@ROWCOUNT
всегда возвращает 0.
MSDN предлагает конструкцию OUTPUT, например
delete from mytable
where datefield = '5-Oct-2008'
output datefield into #doomed
select count(*)
from #doomed
на самом деле это не удается из-за синтаксической ошибки.
Есть идеи?





Создайте временную таблицу с одним столбцом, id.
Вставьте в временную таблицу, выбрав идентификаторы, которые вы хотите удалить. Это дает вам ваш счет.
Удалите из таблицы, где находится идентификатор (выберите идентификатор из временной таблицы)
Это действительно приведет к плохой производительности, запрос займет как минимум в 2 раза больше времени, что может быть значительным временем, если вы обрабатываете много записей. Но творческое мышление!
Вы пробовали SET NOCOUNT OFF?
Я думал, что пробовал это - но, видимо, не пробовал, потому что это сработало как шарм - спасибо.
MSDN, кажется, говорит, что SET NOCOUNT влияет на распечатку. Почему это влияет на @@ROWCOUNT? Разве он не должен всегда возвращать количество удаленных строк (в OP)?
*** Это предположение *** Я думаю, это потому, что установка NOCOUNT сообщает системе, что ей не нужно отслеживать счетчики, чтобы сделать вещи более эффективными.
В вашем примере @@ROWCOUNT должен работать - это правильный способ узнать количество удаленных строк. Если вы пытаетесь удалить что-то из своего приложения, вам необходимо использовать SET NOCOUNT ON.
Согласно MSDN @@ ROWCOUNT функция обновляется, даже когда SET NOCOUNT включен, поскольку SET NOCOUNT влияет только на сообщение, которое вы получаете после выполнения.
Так что, если вы пытаетесь работать с результатами @@ROWCOUNT, например, из ADO.NET, то SET NOCOUNT ON определенно должен помочь.
Я использую @@ ROWCOUNT именно для этой цели в SQL2000 без проблем. Убедитесь, что вы случайно не сбрасываете этот счетчик, прежде чем проверять его (BOL: «Эта переменная устанавливается в 0 любым оператором, который не возвращает строки, например оператором IF»).
Из любопытства, как вы называете процедуру? (Я предполагаю, что это хранимая процедура?). Причина, по которой я спрашиваю, заключается в том, что существует разница между возвращаемым значением хранимой процедуры (которое в данном случае будет 0) и результатом набора строк, который в данном случае будет одной строкой с одним столбцом. В ADO.Net к первому можно получить доступ с помощью параметра, а ко второму - с помощью SqlDataReader. Вы, возможно, ошибочно принимаете возвращаемое значение процедуры за количество строк?
Это был код в одном месте (но да, в хранимой процедуре) - я удалял некоторые данные, а затем записывал этот факт в таблицу состояния, поэтому на самом деле это не было случаем путаницы с возвращаемыми значениями.
Просто сделай это:
SET NOCOUNT off ;
SELECT @p1 = @@ROWCOUNT
где p1 - выходной параметр, установленный вами в хранимой процедуре. Надеюсь, это поможет.
Я нашел случай, когда вы не можете использовать @@rowcount, например, когда вы хотите знать отдельное количество значений, которые были удалены, вместо общего количества. В этом случае вам нужно будет сделать следующее:
delete from mytable
where datefield = '5-Oct-2008'
output deleted.datefield into #doomed
select count(distinct datefield)
from #doomed
Синтаксическая ошибка в OP была связана с тем, что output не включал deleted перед именем поля datefield.
Хотя что-то, что могло бы работать, накладные расходы на что-то подобное - пустая трата.