fin*_*ook 25 t-sql sql-server stored-procedures sql-server-2008
我有以下表格:
DataValue
DateStamp ItemId Value
---------- ------ -----
2012-05-22 1 6541
2012-05-22 2 12321
2012-05-21 3 32
Run Code Online (Sandbox Code Playgroud)
tmp_holding_DataValue
DateStamp ItemId Value
---------- ------ -----
2012-05-22 1 6541
2012-05-22 4 87
2012-05-21 5 234
Run Code Online (Sandbox Code Playgroud)
DateStamp
并且ItemId
是主要的关键列.
我正在做一个插件,它会在一天中定期运行(在存储过程中):
insert into DataValue(DateStamp, ItemId, Value)
select DateStamp, ItemId, Value from tmp_holding_DataValue;
Run Code Online (Sandbox Code Playgroud)
这会将数据从保持表(tmp_holding_DataValue
)移动到主数据表(DataValue
)中.然后截断保持表.
问题是,如示例中所示,保持表可以包含主表中已存在的项.由于密钥不允许重复值,因此过程将失败.
一种选择是在insert proc上放置一个where子句,但主数据表有1000万+行,这可能需要很长时间.
是否还有其他方法可以让程序在尝试插入时跳过/忽略重复项?
Aar*_*and 28
INSERT dbo.DataValue(DateStamp, ItemId, Value)
SELECT DateStamp, ItemId, Value
FROM dbo.tmp_holding_DataValue AS t
WHERE NOT EXISTS (SELECT 1 FROM dbo.DataValue AS d
WHERE DateStamp = t.DateStamp
AND ItemId = t.ItemId);
Run Code Online (Sandbox Code Playgroud)
pap*_*zzo 20
您可以将PK指定为忽略重复键=是.然后它只会给出一个警告重复键被忽略并继续.我不猜.我测试了这个.
我发现我不能这样做是SMSS.必须通过脚本删除并重新创建索引.但是您可以右键单击索引,选择drop并重新创建,然后只需更改Ignore Duplicate Key = Yes.对我来说,SMSS没有立即显示更改.
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[PKallowDup]') AND name = N'PK_PKallowDup')
ALTER TABLE [dbo].[PKallowDup] DROP CONSTRAINT [PK_PKallowDup]
GO
USE [test]
GO
/****** Object: Index [PK_PKallowDup] Script Date: 05/22/2012 10:23:13 ******/
ALTER TABLE [dbo].[PKallowDup] ADD CONSTRAINT [PK_PKallowDup] PRIMARY KEY CLUSTERED
(
[PK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = ON, IGNORE_DUP_KEY = ON, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
或者我认为你可以使用外连接
INSERT dbo.DataValue(DateStamp, ItemId, Value)
SELECT t.DateStamp, t.ItemId, t.Value
FROM dbo.tmp_holding_DataValue AS t
left join dbo.DataValue AS d
on d.DateStamp = t.DateStamp
AND d.ItemId = t.ItemId
WHERE d.DateStamp is null
and d.ItemId in null
Run Code Online (Sandbox Code Playgroud)
Qua*_*noi 17
在SQL Server 2008+
:
MERGE
INTO dataValue dv
USING tmp_holding_DataValue t
ON t.dateStamp = dv.dateStamp
AND t.itemId = dv.itemId
WHEN NOT MATCHED THEN
INSERT (dateStamp, itemId, value)
VALUES (dateStamp, itemId, value)
/*
WHEN MATCHED THEN
UPDATE
value = t.value
*/
-- Uncomment above to rewrite duplicates rather than ignore them
Run Code Online (Sandbox Code Playgroud)