2009-03-30 2 views
7

У меня есть инструкция обновления, которая обновляет таблицу. И есть столбец, в котором записано последнее измененное время. Если данные в определенной строке не были изменены, я не хочу изменять последнее измененное время.Лучший способ проверить, была ли строка обновлена ​​в SQL

Каков наилучший способ проверить, изменит ли инструкция обновления строку данных или нет.

Спасибо,

+0

Не могли бы вы предоставить некоторые сведения о том, какой язык/фреймворк вы используете? Например, я думаю, что mysql_query в PHP возвращает количество строк, обновленных в операциях обновления. – kyle

+0

Я использую C#/T-sql /Asp.Net –

ответ

9

Проверьте старые против новых данных в коде вместо того, чтобы делать это в запросе.

Не нужно беспокоить уровень БД излишне, если данные вообще не меняются.

Короче говоря, если данные не изменялись, не отправляйте инструкцию UPDATE.

+0

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

+0

Я согласен с @jcinacio, но вопрос с OPs остается, если мы пойдем по пути @ jcinacio. Итак, если OP использует sql 2005/2008, то предложение OUTPUT может использоваться для сравнения новых и старых значений. См. Мой ответ ниже. – IsmailS

1

Если вы хотите сделать это превентивно, единственный способ, которым я могу думать, что вы это сделаете, - изменить предложение WHERE оператора обновления, чтобы сравнить существующее значение с новым значением (для КАЖДОГО значения). Если ANY из них не равны, то обновление должно иметь место.

2

Один из способов - начать транзакцию, выбрать содержимое строки и сравнить ее с тем, что вы собираетесь обновлять. Если они не совпадают, выполните обновление и завершите транзакцию. Если они совпадают, откат транзакции.

1

Именно тогда DAL удобен. Он отслеживает все столбцы, поэтому, если ни один не изменился, я даже не отправляю инструкцию UPDATE в базу данных.

1

Похоже, что вы проходите через таблицу и изменяете некоторые строки, затем вы хотите снова вернуться в таблицу через таблицу и обновить временную метку для строк, которые были только что изменены.

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

UPDATE myTable 
SET retailprice = wholesaleprice * 1.10, 
    lastmodified = GetDate() 
WHERE ... 

Или вы выдача оператора обновления на все строки, но для большинства строк, он просто устанавливает его стоимость это уже есть? Не делай этого. Исключить те строки, которые не будут изменены в вашем ИНЕКЕ:

UPDATE myTable 
SET retailprice = wholesaleprice * 1.10, 
    lastmodified = GetDate() 
WHERE retailprice <> wholesaleprice * 1.10 
0

Вы можете написать INSTEAD OF UPDATE триггера в T-SQL, где вы могли бы сделать то, что было предложено выше в DAL слое - сравнение значения в существующей записи по сравнению с значениями в инструкции обновления и либо применить обновление, либо нет. Вы можете использовать функцию Columns_Updated() в триггере, чтобы увидеть, обновлено ли что-либо, и действовать соответствующим образом.

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

+0

Как вы знаете, что это настройка SQL Server из-за истории или предыдущих вопросов? –

+0

Вы правы - я этого не делаю. Я сделал предположение. Однако другие базы данных SQL (Oracle, например) также реализуют аналогичные функции. Не уверен в mySQL, Postgres и т. П. –

1

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

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

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

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

1

Если вы используете sql 2005/2008, вы можете сделать следующее в хранимой процедуре.

update newTable 
set  readKey='1' 
output inserted.id, 
     inserted.readKey as readKey, 
     deleted.readKey as prevReadKey 
into @tempTable 
where id = '1111' 

Затем вы можете выбрать из @tempTable, чтобы проверить, если prevReadKey и ReadKey имеют аналогичное значение, если оба имеют аналогичное значение, которое вы можете сбросить настройки последнего изменения DateTime.

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

P.S. ПРИМЕЧАНИЕ. - Указанный запрос может быть синтаксически неправильным, поскольку он не проверен. Но именно так может быть решена ваша проблема. Я сделал это следующим образом, используя предложение OUTPUT с оператором Merge в одном из моих проектов, и это также можно сделать с помощью инструкции обновления. Вот reference of OUTPUT Clause

Смежные вопросы