1

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

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它不应该插入,因为这个人本月已经取货了。任何想法如何实现它?

4

3 回答 3

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_前缀。Microsoft 已保留该前缀供自己使用(请参阅命名存储过程,并且您确实会在将来某个时候冒名称冲突的风险。这对您的存储过程性能也很不利。最好只是简单地避免sp_并使用其他东西作为前缀 - 或者根本没有前缀!

于 2013-03-23T22:01:31.343 回答
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 关于.

于 2013-03-23T23:05:14.230 回答
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
于 2013-03-23T22:05:16.950 回答