[英]Insert record only if record does not already exist in table
我想知道是否有辦法只在表中沒有包含該記錄的情況下將記錄插入表中?
是否有查詢會執行此操作,還是需要存儲過程?
你沒有說什么版本的SQL Server。 如果SQL Server 2008可以使用MERGE
注意:通常使用Merge作為Upsert,這是我最初認為的問題,但它沒有WHEN MATCHED
子句並且只是WHEN NOT MATCHED
子句有效,所以也適用於這種情況。 示例用法。
CREATE TABLE #A(
[id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[C] [varchar](200) NOT NULL)
MERGE #A AS target
USING (SELECT 3, 'C') AS source (id, C)
ON (target.id = source.id)
/*Uncomment for Upsert Semantics
WHEN MATCHED THEN
UPDATE SET C = source.C */
WHEN NOT MATCHED THEN
INSERT (id, C)
VALUES (source.id, source.C);
就執行成本而言,當要完成插入時,兩者看起來大致相等......
但是在第二次運行時,沒有插件可以完成馬修的答案看起來成本更低。 我不確定是否有辦法改善這一點。
測試腳本
select *
into #testtable
from master.dbo.spt_values
CREATE UNIQUE CLUSTERED INDEX [ix] ON #testtable([type] ASC,[number] ASC,[name] ASC)
declare @name nvarchar(35)= 'zzz'
declare @number int = 50
declare @type nchar(3) = 'A'
declare @low int
declare @high int
declare @status int = 0;
MERGE #testtable AS target
USING (SELECT @name, @number, @type, @low, @high, @status) AS source (name, number, [type], low, high, [status])
ON (target.[type] = source.[type] AND target.[number] = source.[number] and target.[name] = source.[name] )
WHEN NOT MATCHED THEN
INSERT (name, number, [type], low, high, [status])
VALUES (source.name, source.number, source.[type], source.low, source.high, source.[status]);
set @name = 'yyy'
IF NOT EXISTS
(SELECT *
FROM #testtable
WHERE [type] = @type AND [number] = @number and name = @name)
BEGIN
INSERT INTO #testtable
(name, number, [type], low, high, [status])
VALUES (@name, @number, @type, @low, @high, @status);
END
IF NOT EXISTS
(SELECT {Columns}
FROM {Table}
WHERE {Column1 = SomeValue AND Column2 = SomeOtherVale AND ...})
INSERT INTO {Table} {Values}
簡而言之,您需要一個保證為您提供返回一行的表:
Insert dbo.Table (Col1, Col2, Col3....
Select 'Value1', 'Value2', 'Value3',....
From Information_Schema.Tables
Where Table_Schema = 'dbo'
And Table_Name = 'Table'
And Not Exists (
Select 1
From dbo.Table
Where Col1 = 'Foo'
And Col2 = 'Bar'
And ....
)
我也看到了野外的這種變化:
Insert Table (Col1, Col2, Col3....
Select 'Value1', 'Value2', 'Value3'....
From (
Select 1 As Num
) As Z
Where Not Exists (
Select 1
From Table
Where Col1 = Foo
And Col2 = Bar
And ....
)
我必須投票支持添加CONSTRAINT
。 這是最簡單,最強大的答案。 我的意思是,看看其他答案有多復雜,我會說他們更難做到(並保持正確)。
缺點:[1]通過閱讀代碼並不明顯,在DB [2]中強制執行唯一性客戶端代碼必須知道捕獲異常。 換句話說,那個追隨你的人可能會想知道“這是怎么回事?”
除此之外:我曾擔心拋出/捕獲異常是一個性能損失,但我做了一些測試(在SQL Server 2005上)並且它並不重要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.