我正在尝试创建将在我的分拣表中插入两个值的过程。
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
它不应该插入,因为这个人已经在本月进行了提取。
任何想法如何实现它?
答案 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