存储过程中的SQL IF / Case

时间:2013-03-23 21:59:33

标签: sql sql-server-2008 stored-procedures insert case

我正在尝试创建将在我的分拣表中插入两个值的过程。

create procedure sp_InsertPickup
@ClientID int,
@PickupDate date 
as 
insert into Pickup (ClientID ,PickupDate )values (@ClientID,@PickupDate)

但是我需要检查这个客户端本月是否已经提取(表中记录)它不应该在表中插入任何新记录。 示例如果表中的数据

ClientID PickupDate
11       03-01-2013

我希望插入ClientId 11 and new PickupDate 03-24-2013它不应该插入,因为这个人已经在本月进行了提取。 任何想法如何实现它?

3 个答案:

答案 0 :(得分:2)

因此,在这种情况下,请使用IF NOT EXISTS

CREATE PROCEDURE dbo.InsertPickup
    @ClientID int,
    @PickupDate date 
AS
   IF NOT EXISTS (SELECT * FROM Pickup 
                  WHERE ClientID = @ClientID 
                    AND MONTH(PickupDate) = MONTH(@PickupDate) 
                    AND YEAR(PickupDate) = YEAR(@PickupDate) )
      INSERT INTO Pickup (ClientID, PickupDate)
      VALUES (@ClientID, @PickupDate)

你可能想以某种方式向调用者表明没有插入数据,因为它已经存在....

作为旁注:您应使用存储过程的sp_前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实在将来的某个时候冒着名字冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免sp_并使用其他东西作为前缀 - 或者根本没有前缀!

答案 1 :(得分:2)

最安全的方法是使用merge或在表上设置约束并捕获错误。

merge更安全的原因是因为它是原子事务。检查存在并然后执行插入是危险的,因为其他人可能已插入(或删除)该行。您可以在存储过程中开始使用事务语义,但是为什么在SQL Server提供merge时会感到烦恼:

merge Pickup as target
using (select @PickupDate, @ClientId) as source(PickupDate, ClientId)
    on target.clientId = source.ClientId and year(source.PickupDate) = year(target.PickupDate) and month(source.PickupDate) = month(target.PickupDate)
when NOT MATCHED then
    insert(PickupDate, ClientId) values(source.PickupDate, source,ClientId);

您可以详细了解merge an

答案 2 :(得分:1)

这是使用IF NOT EXISTS

实现它的方法
create procedure sp_InsertPickup
    @ClientID int,
    @PickupDate date 
as 
    IF NOT EXISTS (SELECT * FROM Pickup 
                            WHERE ClientID = @ClientID 
                            AND DATEPART(mm,PickupDate) = DATEPART(mm,@PickupDate)
                            AND DATEPART(yy,PickupDate) = DATEPART(yy,@PickupDate))
    BEGIN
        insert into Pickup (ClientID ,PickupDate )values (@ClientID,@PickupDate)
    END
begin
end