SQL: триггер устанавливает столбец в значение null

#sql #sql-server #sql-server-2008

#sql #sql-сервер #sql-server-2008

Вопрос:

Я создал триггер для установки столбца в значение null, где столбец имеет значение, большее GETDATE()

 ALTER TRIGGER [dbo].[Null_Time_Trigger3]

  on [dbo].[Parking]
  FOR insert
  as
  update Parking
  set Column = NULL
  from Parking
  where Column >= CAST(GETDATE () AS TIME)
  

похоже, по прошествии времени триггер ничего не делает? время все еще находится в столбце, и столбец не имеет значения NULL .

Есть идеи, как это решить??

Есть ли способ сделать это (Setting the column to null) other than triggers???

С уважением.

Комментарии:

1. Ваш триггер срабатывает при вставке записи, так что же это значит, когда проходит время ?

2.@Marco Столбец имеет значение time, нормально? когда system time (GETDATE) больше времени в column , триггер должен установить для этого Column значение NULL

3. Прежде всего, я думаю, вам следует использовать < в определении вашего триггера. В любом случае этот триггер срабатывает ТОЛЬКО при вставке новой строки в db и действует ТОЛЬКО на эту строку, не на предыдущие!!!

4. Триггеры предназначены не для этого.

Ответ №1:

insert триггеры срабатывают только при выполнении инструкции insert. Если нет insert операции, ваш триггер не будет запущен.

Поскольку ваш триггер ссылается на Parking саму таблицу, а не на inserted таблицу, он может работать с insert, но это совершенно не то, для чего предназначены триггеры.

В SQL Server нет временных триггеров, которые автоматически NULL запускали бы столбцы по истечении времени (как, кажется, вы могли ожидать).

Вместо этого вы можете сделать CASE WHEN Column < CAST(GETDATE () AS TIME) THEN Column END AS Column в своем SELECT .

Комментарии:

1. В то же время: ваш ответ совпадает с моим комментарием 🙂

2. @Martin да, строка, которой я хочу присвоить значение null, вставлена, на самом деле имеет значение

3. @Martin: есть ли какой-либо способ сделать это, кроме триггера?

4. @Humam — Если вам нужно присвоить столбцу значение null по истечении содержащегося в нем значения времени, вы могли бы использовать SQL Agent для планирования задания, которое выполняется периодически и выполняет это, или вы могли бы использовать Service Broker — Возможно, этот последний вариант позволил бы вам настроить более сложную систему, в которой процесс запускается только при необходимости, не уверен в этом. Действительно ли необходимо обнулять столбцы? Разве ваш соответствующий код не может просто проверить, является ли column < getdate() ?

5. @Martin: поскольку природа моей системы заключается в резервировании парковки, они должны иметь значение null, чтобы парковочные места могли быть снова доступны.

Ответ №2:

Прежде всего, я думаю, вам следует использовать < в определении вашего триггера. В любом случае этот триггер срабатывает ТОЛЬКО при вставке новой строки в db и действует ТОЛЬКО на эту строку, не на предыдущие!!!
Вы могли бы сделать это с помощью одного запроса:

 UPDATE Parking SET `Column`=NULL
WHERE `Column` < CAST(GETDATE () AS TIME)
  

ОТРЕДАКТИРОВАНО:

 CREATE TRIGGER [dbo].[Null_Time_Trigger4]
on [dbo].[Parking]
FOR INSERT,UPDATE
AS BEGIN
    UPDATE Parking SET `Column`=NULL
    WHERE `Column` < CAST(GETDATE () AS TIME)
END
  

Комментарии:

1. @Marco: даже когда строка со временем, меньшим, чем GETDATE(), не изменяет его на NULL, есть ли какой-либо способ сделать это, кроме триггера?

2. @Marco: могу ли я запустить запрос автоматически?

3. @Humam Shbib: если вы используете приложение (написанное, например, на C #), вы могли бы создать таймер, который выполняет этот запрос каждую секунду… Или вы можете вставить триггер в db, который при каждом добавлении строки выполняет и этот другой запрос…

4. @Marco: и как возможен второй вариант?

5. @Humam Shbib: Я не знаю, работает ли триггер в моем отредактированном сообщении, но он должен делать то, что вам нужно, каждый раз, когда вы вставляете / обновляете строку в таблице парковки.

Ответ №3:

Вы могли бы добавить вычисляемый столбец, что-то вроде этого:

 CREATE TABLE
(
...
Column  DATETIME,
CurrentColumn  AS CASE WHEN DATETIME < SYSDATETIME() THEN DATETIME END
....
)
  

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