Подсчет количества удаленных строк в хранимой процедуре SQL Server

Есть ли в 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

на самом деле это не удается из-за синтаксической ошибки.

Есть идеи?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
51
0
69 410
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Создайте временную таблицу с одним столбцом, id.

Вставьте в временную таблицу, выбрав идентификаторы, которые вы хотите удалить. Это дает вам ваш счет.

Удалите из таблицы, где находится идентификатор (выберите идентификатор из временной таблицы)

Хотя что-то, что могло бы работать, накладные расходы на что-то подобное - пустая трата.

Mitchel Sellers 06.10.2008 17:40

Это действительно приведет к плохой производительности, запрос займет как минимум в 2 раза больше времени, что может быть значительным временем, если вы обрабатываете много записей. Но творческое мышление!

Karel-Jan Misseghers 19.07.2013 18:35
Ответ принят как подходящий

Вы пробовали SET NOCOUNT OFF?

Я думал, что пробовал это - но, видимо, не пробовал, потому что это сработало как шарм - спасибо.

Unsliced 06.10.2008 17:07

MSDN, кажется, говорит, что SET NOCOUNT влияет на распечатку. Почему это влияет на @@ROWCOUNT? Разве он не должен всегда возвращать количество удаленных строк (в OP)?

noelicus 19.01.2015 17:20

*** Это предположение *** Я думаю, это потому, что установка NOCOUNT сообщает системе, что ей не нужно отслеживать счетчики, чтобы сделать вещи более эффективными.

wcm 22.01.2015 21:41

В вашем примере @@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. Вы, возможно, ошибочно принимаете возвращаемое значение процедуры за количество строк?

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

Unsliced 09.10.2008 15:32

Просто сделай это:

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.

Другие вопросы по теме