我正在检查记录是否存在,然后将其插入到表中(并且此方法似乎适用于我已经使用的其他存储过程)但是对于这个特定的存储过程,它不会插入任何内容,即使表是空的,为什么不呢?
CREATE PROCEDURE spInsertMovieHasTrailer
@movieID int,
@name varchar(50)
AS
BEGIN
SELECT @name = name, @movieID = movieID
FROM MovieHasTrailer
WHERE name = @name and movieID = @movieID
IF @name IS NULL and @movieID IS NULL
BEGIN
INSERT INTO MovieHasTrailer
(
movieID,
name
)
Values (
@movieID,
@name
)
END
END
执行如下:
execute spInsertMovieHasTrailer 1, 'Test'
答案 0 :(得分:6)
我会直接将其构建到insert
中,而不是使用if
逻辑。 if
引入了种族条件:
INSERT INTO MovieHasTrailer
SELECT movieID, name
FROM (SELECT @movieID as movieID, @name as name) t
WHERE NOT EXISTS (SELECT 1
FROM MovieHasTrailer mht
WHERE mht.MovieId = t.MovieID AND mht.name = t.name
);
请注意,这假设您需要id和名称才能匹配电影。我认为id
就足够了。
另外,我真正要做的是在MovieHasTrailer(MovieId)
或MovieHasTrailer(MovieId, Name)
上都有一个唯一索引。如果存在插入错误,请使用try
/ catch
块。
答案 1 :(得分:1)
您没有进行插入的原因是,如果查询没有返回记录,以下代码将不会更改@name和@movieID的值
SELECT @name = name, @movieID = movieID
FROM MovieHasTrailer
WHERE name = @name and movieID = @movieID
无论@name和@movieID的值是什么,您传入存储过程都保持不变。我假设您没有传入空值,因此永远不会执行IF块。
答案 2 :(得分:0)
你的select into变量可能会返回多个值而你会收到错误,最好使用if not exists
:
IF NOT EXISTS
(
SELECT name, movieID
FROM MovieHasTrailer
WHERE name = @name and movieID = @movieID
)
BEGIN
INSERT INTO MovieHasTrailer
(
movieID,
name
)
Values (
@movieID,
@name
)
END
答案 3 :(得分:0)
您可以尝试这种方式,也可以实现目标,也可以节省您的时间。
INSERT INTO MovieHasTrailer
SELECT @movieID as movieID, @name as name
except
select MovieId, name
FROM MovieHasTrailer mht
where MovieId = @MoveID
答案 4 :(得分:0)
我会通过标准MERGE
声明来做到这一点:
Create table t(id int, name nvarchar(max))
Declare @id int = 1, @name nvarchar(max) = 'Mission imposible'
Merge t using (select @id, @name) as s(id, name)
on t.id = s.id
when not matched then
insert(id, name) values(s.id, s.name);
您还可以在此声明中添加WHEN MATCHED THEN UPDATE
,WHEN NOT MATCHED BY SOURCE THEN DELETE
。