Как я могу предотвратить запись, вставленную триггером SQL, пытающимся установить столбец идентификаторов - PullRequest
0 голосов
/ 26 апреля 2019

Я пытаюсь создать таблицу 'history', которая обновляется каждый раз, когда обновляется строка в исходной таблице.

Вот код (SQL Server), который я использую для создания таблицы истории:

DROP TABLE eventGroup_History 

SELECT 
    CAST(NULL AS UNIQUEIDENTIFIER) AS NewId, 
    CAST(NULL AS varchar(255)) AS DoneBy, 
    CAST(NULL AS varchar(255)) AS Operation, 
    CAST(NULL AS datetime) AS DoneAt, 
    * 
INTO 
    eventGroup_History 
FROM 
    eventGroup 
WHERE 
    1 = 0
GO

ALTER TABLE eventGroup_History 
ALTER COLUMN NewId UNIQUEIDENTIFIER NOT NULL
go

ALTER TABLE eventGroup_History 
ADD PRIMARY KEY (NewId)
GO

ALTER TABLE eventGroup_History 
ADD CONSTRAINT DF_eventGroup_History_NewId DEFAULT NewSequentialId() FOR NewId
GO

Триггер создан так:

drop trigger eventGroup_LogUpdate
go

create trigger eventGroup_LogUpdate 
on dbo.eventGroup
for update
as
  declare @Now as DateTime = GetDate()
  set nocount on

  insert into eventGroup_History
      select @Now, SUser_SName(), 'update-deleted', *
      from deleted

  insert into eventGroup_History
      select SUser_SName(), 'update-inserted', @Now, *
      from inserted
go

exec sp_settriggerorder @triggername = 'eventGroup_LogUpdate', @order = 'last', @stmttype = 'update'

Но когда я обновляю строку в SQL Server Management Studio, я получаю сообщение:

Данные в строке 2 не были зафиксированы.
Источник ошибки: поставщик данных .Net SqlClient.
Сообщение об ошибке: не удалось выполнить преобразование при преобразовании строки символов в уникальный идентификатор.

enter image description here

Я думаю, что триггер пытается вставить SUserSName() в качестве первого столбца строки, но это PK NewId:

enter image description here

Других столбцов уникального идентификатора в таблице нет.

Если я добавлю строку из сетки редактирования SQL Management Studio, она будет добавлена ​​без указания значения NewId.

Итак, почему триггер SQL Server пытается заполнить NewId первым элементом в предложении INSERT INTO, а не пропускать его, чтобы обычная операция IDENTITY давала значение?

(И как мне остановить это, чтобы сработал триггер?)

Ответы [ 2 ]

3 голосов
/ 26 апреля 2019

Поскольку автоматический пропуск применяется только к столбцам IDENTITY - столбец GUID, установленный с ограничением NewSequentialId (), во многом похож на IDENTITY, но не в этом.

Вы можете достичь того, что ищетеявно указав столбцы для INSERT.

3 голосов
/ 26 апреля 2019

Если вы собираетесь использовать значение по умолчанию для столбца NewId, вам необходимо явно указать имена столбцов в операторах INSERT.По умолчанию SQL Server вставляет столбцы в том порядке, в котором они перечислены в SELECT, если вы не укажете достаточно информации, чтобы поступить иначе.Явное перечисление столбцов является наилучшей практикой, так или иначе, чтобы избежать такого непредвиденного результата.

Таким образом, ваши утверждения в конечном итоге будут выглядеть так:

INSERT INTO eventGroup_History
  (
    DoneBy,
    Operation,
    DoneAt,
    <All the other columns that are masked by the *>
  )
SELECT....
...