SQL Server 2008。
我有几段代码一起工作,效果很奇怪所以我决定分享。
我有一个包含电子邮件的表 - 为简单起见,假设有2列: ID identity(1,1)int主键 email varchar(900)
此外,电子邮件列中还有一个唯一键,其中IGNORE_DUP_KEY = ON。
问题的另一方面是合并声明:
merge into dbo.email
using (
select distinct email t from #t
) p
ON t = email
when not matched by target then
insert (email) values (t);
值得注意的是,#t基本上是(为了这个查询的目的)一个包含电子邮件varchar(500)的列表。
令人惊讶的是查询失败:
“违反UNIQUE KEY约束'uq_email'。无法在对象dbo.email中插入重复键”
然而,这完美无缺:
insert into dbo.email (email) select email from #t
虽然我显然可以解决这个问题(无论如何插入语句更快,所以它是一种方法)我不知道为什么MERGE语句失败。任何想法,任何人?
编辑:完整用例: 第1步:
create table #temp (
col1 varchar(500),
col2 varchar(500),
col3 varchar(500),
col4 varchar(500),
col5 varchar(500),
email varchar(500),
id int)
第2步:
为了多种目的,从CSV文件填充#temp
第3步:
合并到dbo.email 使用( 从#temp中选择不同的电子邮件 )p ON t =电子邮件 当没有与目标匹配时 插入(电子邮件)值(t);
步骤0 - dbo.email的CREATE脚本:
CREATE TABLE dbo.email (
id int identity(1,1) not null,
email varchar(900) null,
loaddate date default null,
constraint [PK__email__1111] PRIMARY KEY CLUSTERED
(
id asc
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON PRIMARY,
CONSTRAINT [uq_email] UNIQUE NONCLUSTERED
(
EMAIL asc
)
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON PRIMARY
) ON PRIMARY
如果不向你提供数十亿字节的数据,我就无法做得更多,这显然是一个问题。
答案 0 :(得分:7)
您的电子邮件列允许null
个值。如果您的目标值为null
且源中的值为null
,则on
表达式中不会匹配这些值。插入第二个null
值时,您将遇到唯一的约束异常。
请改为尝试:
merge into dbo.email
using (
select distinct email t from #t where email is not null
) p
ON t = email
when not matched by target then
insert (email) values (t);
<强>更新强>
关于ignore_dup_key
,您应该阅读merge声明文档中的备注部分:
如果目标上的任何唯一索引将IGNORE_DUP_KEY设置为ON 表,MERGE忽略此设置。
要在SQL Server中使用允许多个空值的唯一约束,您应该添加唯一的过滤索引。
create unique index UX_xx on TableName(ColName) where ColName is not null