【问题标题】:TSQL is expecting the identity column to be inserted when using an instead of insert triggerTSQL 期望在使用而不是插入触发器时插入标识列
【发布时间】:2013-07-08 16:01:52
【问题描述】:

我正在设置一个视图 (foo),以代替同名的表。新视图将使用 3 个子表(A、B、C)而不是原始表。我正在使用而不是触发器来完成此操作。

CREATE VIEW [dbo].[foo]
AS
select
    b2 as oldkey,
    b3 as boat,
    c2 as state,
    a2 as name
from
    A
    join B on a1 = b1
    join C on a1 = c1

foo 列:oldkey(身份)|船| 高分辨率照片| CLIPARTO状态 |名字

我的问题是我有一个大型代码库,它被写入 foo 中,如下所示:

insert into foo
values
('fishing boat', 'California', 'Skipper')

但此代码当前无法正常工作,因为 insert-of-insert/view 也希望提供键值。键值是B表的标识,不需要插入。

错误:“列名或提供的值的数量与表定义不匹配。”

我需要进行哪些更改才能使已存在的插入代码库继续运行?

【问题讨论】:

  • INSTEAD OF INSERT 触发器中,您需要插入第一个表,获取新定义的标识列值,然后填充包括该外键在内的其他表。您应该向我们展示您的触发代码!
  • @marc_s 我确实这样做了。我所有用于插入/更新/删除的代码都有效。我认为问题在于我如何声明视图。
  • 呃,那也给我们看看?
  • @AaronBertrand 我已经为视图添加了通用代码。

标签: sql sql-server tsql triggers


【解决方案1】:

由于INSERT 没有指定预期的列,而是使用了隐式的标识列跳过技巧,我认为你只是不走运。

这是一个很好的例子,说明为什么指定列名是最佳实践。如果原始代码指定了这样的列名:

INSERT INTO dbo.Foo (ItemType, Location, Name)
VALUES ('fishing boat', 'California', 'Skipper');

然后插入将起作用(通过以下修改)。

INSERT 中指定的列到视图时,您可以通过修改视图跳过identity 列,使该列不再保留identity 属性或PK 状态在视图的元数据中。你可以这样做:

SELECT
   IdentityColumn = IdentityColumn * 1, -- a math expression removes `identity`
   OtherColumns
FROM
   TablesHere
;

【讨论】:

  • 如果您仍然遇到问题,请显示示例代码和引擎提供的确切错误消息,而不是仅将问题描述为“期望也提供键值”。这将更好地指导那些希望帮助你的人。
  • 该修复似乎不起作用。我没有包括具体错误,因为它只是一般错误:“列名或提供的值的数量与表定义不匹配。”我编辑了帖子以显示错误,因为人们可能认为这是我的解释中关于身份的错误。
  • 不幸的是,我也得出了同样的结论。我找不到其他方法,但我想问也无妨。谢谢!
  • 幸运的是,@Ryan,幸运的是。 :) 如果您在没有任何人建议您相同的情况下得出结论,那可能会很不幸。这样一来,您可能不得不怀着沉重的心情进行更改,怀疑该决定是否确实正确。事实上,你肯定知道有人支持你。 :)
  • @AndriyM 非常正确。感谢您的积极旋转! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 2019-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多