SCD 类型 2 和标识列插入错误
Posted
技术标签:
【中文标题】SCD 类型 2 和标识列插入错误【英文标题】:SCD Type 2 and Insert Error with Identity Column 【发布时间】:2019-09-10 13:10:08 【问题描述】:在我的数据仓库表中插入记录时遇到问题。我有一个代理键,它为每条记录创建自动递增 1。我收到错误消息:
表“TARGET”中标识列的显式值只能 在使用列列表并且 IDENTITY_INSERT 为 ON 时指定
下面的代码sn-p:
INSERT INTO [DW_Table] (Valid_Start_Date, Valid_End_Date, Current_Flag, Col1, Col2, Col3)
SELECT
Getdate() AS Valid_Start_Date, NULL AS Valid_End_Date, 1 as Current_Flag, Col1, Col2,Col3
FROM (
MERGE INTO [DW_Table] AS TARGET
USING ([Base_Table]) AS SOURCE
ON ( SOURCEC.Account_Key = TARGET.Account_Key
AND TARGET.Current_Flag = 1)
WHEN MATCHED .................................
我已尝试列出字段,因为我知道问题在于尝试将记录插入自动递增字段。我已将其作为“USING”基表行的一部分执行,但仍然出现错误。
有人可以指点一下吗?
谢谢
【问题讨论】:
您的插入列与所选列不匹配。1 as Current_Flag
将进入 Col1
进入插入列表。
IN 除了@WEI_DBA 指出的问题之外,您的 TARGET 表还有一个 IDENTITY 列,该列会自动生成该列的值。因此,您需要 a) 在 INSERT 中不包含该列,或者 b) 在错误状态下打开 IDENTITY_INSERT。可能是 A,但这取决于您的情况。
查询中有错字,所以我错过了 Insert Into 中的 Current_Flag。我现在已经修改了。我没有在 INSERT 中包含 IDENTITY 列,但我仍然得到同样的错误
任何触发器? WHEN MATCHED 之后发生了什么?您是否可以在不使用MERGE 的情况下执行此插入?甚至可以只用 INSERT 进行测试,看看 MERGE 语句是否有问题。
从 WHEN MATCHED 开始,我会检查我的字段以确定是否有任何行发生了变化。如果他们有我将 current_flag 设置为 0,插入一个新行并将其设置为当前。 INSERT 可以自己正常工作。看来这是 MERGE 的问题。
【参考方案1】:
试试这样的:
use tempdb
go
drop table if exists dw_table
drop table if exists dw_table_stg
create table DW_Table
(
Id int identity,
Valid_Start_Date date,
Valid_End_Date date,
Current_Flag bit,
Account_Key int ,
constraint uk_account_current unique (Account_Key, Current_Flag),
Col1 int,
Col2 int,
Col3 int
)
insert into DW_Table (Account_Key,Col1, Col2, Col3, Current_Flag)
values (1,2,3,4,1),(2,2,3,4,1),(3,2,3,4,1)
go
declare @DW_Table_stg table( Account_Key int primary key, Col1 int, Col2 int, Col3 int)
insert into @DW_Table_stg (Account_Key,Col1, Col2, Col3) values (1,2,5,12)
insert into [DW_Table]
( Account_Key, Valid_Start_Date, Valid_End_Date, Current_Flag, Col1, Col2, Col3)
select Account_Key, Getdate(), NULL, 1, Col1, Col2, Col3
from
(
merge into [DW_Table] AS t
using @DW_Table_stg AS s
ON ( s.Account_Key = t.Account_Key )
when matched and t.Current_Flag = 1 and checksum(s.Col1,s.Col2,s.Col3) <> checksum(t.Col1,t.Col2,t.Col3)
then update set t.Current_flag = 0, t.Valid_End_Date = getdate()
when not matched
then insert (Valid_Start_Date, Valid_End_Date, Current_Flag,Account_Key, Col1, Col2, Col3)
values (getdate(), null, 1, s.Account_Key,s.Col1, s.Col2, s.Col3)
output $action [ActionType], s.*
) d
where [ActionType] = 'UPDATE'
select *
from DW_Table
order by current_flag desc, Account_key
【讨论】:
【参考方案2】:根据提供的代码 sn-p,以下是您的错误消息试图制作的引用...
目标 = [DW_TABLE] COLUMNS = (Valid_Start_Date, Valid_End_Date, Current_Flag, Col1, Col2, Col3)
这意味着 DW_TABLE 中列出的列之一被定义为 IDENTITY KEY,因此您的 INSERT 语句不应为其指定值。
你能分享完整的合并查询和 DW_TABLE 的列定义吗?
此外,连接键是“SOURCEC”而不是“SOURCE”。这只是一个错字吗?
【讨论】:
以上是关于SCD 类型 2 和标识列插入错误的主要内容,如果未能解决你的问题,请参考以下文章