我想知道是否有办法仅在表尚未包含该记录的情况下将记录插入表中?
是否有查询可以执行此操作,或者我需要存储过程吗?
最佳答案
您没有说明 SQL Server 的版本。如果是 SQL Server 2008,您可以使用 MERGE
注意:通常使用合并进行更新插入,这就是我最初认为问题所问的问题,但它在没有 WHEN MATCHED
子句并且只有 WHEN NOT MATCHED 的情况下有效
子句 so 也适用于这种情况。用法示例。
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);
就执行成本而言,当要完成插入时,两者看起来大致相等......
Link to plan images for first run
但是在第二次运行时,当没有插入需要完成时,马修的答案看起来成本较低。我不确定是否有办法改进这一点。
Link to plan images for second run
测试脚本
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
关于sql - 仅当表中尚不存在记录时插入记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3268866/