Cha*_*rns 20 sql sql-server sql-server-2008-r2
我有3个表:audioFormats,videoFormats和fileInfo.我有一个事务,当我插入fileInfo表时,该插入包括来自audioFormats和videoFormats的FK.如果音频格式或视频格式不在这些表中,则插入到后面的表中,然后将生成的(或现有的)ID值插入到fileInfo中.
如何仅在该值不存在时才有效地插入值,但是获取值的ID是否已经存在或仅使用SQL(可能是事务)重新插入.
我可以插入一个值,如果它尚不存在:
INSERT INTO audioformats (audioformat)
VALUES(@format)
WHERE NOT EXISTS (SELECT 1 FROM audioformats WHERE audioformat = @format)
Run Code Online (Sandbox Code Playgroud)
我可以从插入中获取插入的ID:
INSERT INTO audioFormats (audioFormat)
VALUES ('Test')
SET @audioFormatId = SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)
如果没有插入,SCOPE_IDENTITY将不会给我ID值.我可以执行标量查询以在可能的插入后获取标识,但似乎我应该能够使用最多一个SELECT和INSERT完成所有这些操作.
Hog*_*gan 13
您可以使用IF语句执行此操作
IF NOT EXISTS(SELECT TOP 1 1 FROM audioformats WHERE audioformat = @format)
BEGIN
INSERT INTO audioFormats (audioFormat)
VALUES ('Test')
SET @audioFormatId = SCOPE_IDENTITY()
END
ELSE
BEGIN
SELECT @audioFormatID = ID FROM audioformats WHERE audioformat = @format
END
Run Code Online (Sandbox Code Playgroud)
或者你可以这样做:
INSERT INTO audioformats (audioformat)
SELECT @format
FROM audioFormats
WHERE NOT EXISTS (SELECT TOP 1 1 FROM audioformats WHERE audioformat = @format)
SELECT @audioFormatID = ID FROM audioformats WHERE audioformat = @format
Run Code Online (Sandbox Code Playgroud)
我将一个答案标记为正确,因为它与我最终的 SQL 最相似,但它并没有真正满足最多使用一个查询和一个插入的原始要求。以下是,并且是我最终使用的:
-- One select
SELECT @audioFormatId = id
FROM audioformats
WHERE audioformat = @audioFormat;
-- Optionally one insert
IF @audioFormatId IS NULL AND @audioFormat IS NOT NULL
BEGIN
INSERT INTO audioFormats (audioFormat)
VALUES (@audioFormat)
SET @audioFormatId = SCOPE_IDENTITY()
END
Run Code Online (Sandbox Code Playgroud)
当对查询的大多数调用实际上执行插入时,Hogan 的回答可能会更快,因为 IF NOT EXISTS 查询比实际返回行的查询快。
在大部分时间该值已经存在的情况下,我的可能会更快,因为这样只会进行一个查询(并且没有 IF NOT EXISTS 查询)。我怀疑空检查是微不足道的。