Вместо триггера при просмотре с использованием слияния не применяются значения таблицы по умолчанию.

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

Следующий пример демонстрирует:

create table tblTest
(
    id uniqueidentifier not null primary key default newid(),
    forename varchar(20),
    surname varchar(20) not null default 'xxyyzz'
)
go

create view vwTest as select * from tblTest
go

create Trigger vwTest_trigger_insteadof_insert_update On vwTest
Instead of Insert, Update As
begin
set nocount on
Merge tblTest t

Using
    inserted i On (t.id = i.id)

When Matched Then
    Update
        Set
        t.forename = i.forename,
        t.surname = i.surname

When Not Matched By Target Then
    Insert
    (
        id,
        forename,
        surname

    )
    Values
    (
        i.id,
        i.forename,
        i.surname

    )
OUTPUT $action, Inserted.*, Deleted.*
;
end
go

--Inserts to physical table work as expected
insert into tblTest (id) values (newid())
insert into tblTest (surname) values ('smith')

--Inserts into updateable view fail as no defaults are set
--from the underlying physical table
insert into vwTest (id) values (newid())
insert into vwTest (surname) values ('jones')

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


person winnt93    schedule 28.10.2012    source источник
comment
Я изменил свой код триггера, чтобы он просто обрабатывал вставку, используя Insert into tblTest Select * from Inserted - та же проблема. Я начинаю думать, что упускаю здесь что-то фундаментальное.   -  person winnt93    schedule 29.10.2012


Ответы (1)


Достаточно просто. Чтобы использовать значение по умолчанию, вы должны либо использовать ключевое слово DEFAULT, либо не включать его в свою вставку. Даже значение NULL имеет значение. В этом случае вы указываете значение во вставке в своем триггере. Если бы вы изменили эту часть с

When Not Matched By Target Then
Insert
(
    id,
    forename,
    surname

)
Values
(
    i.id,
    i.forename,
    i.surname

)

to

When Not Matched By Target Then
Insert
(
    id,
    forename,
    surname

)
Values
(
    i.id,
    i.forename,
    DEFAULT

)

Вы увидите значение по умолчанию для фамилии. К сожалению, это не очень поможет вам в том, что вы пытаетесь сделать. Лучшее решение, которое я могу придумать (и оно не очень хорошее), - это поместить ваши значения по умолчанию в триггер, используя isnulls.

When Not Matched By Target Then
Insert
(
    id,
    forename,
    surname

)
Values
(
    ISNULL(i.id,newid()),
    i.forename,
    ISNULL(i.surname,'xxyyzz')

)

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

person Kenneth Fisher    schedule 17.03.2013