2013-03-23 2 views
1

Я пытаюсь создать процедуру, которая будет вставлять два значения в таблицу Pickup.SQL IF/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 он должен просто не вставить, потому что этот человек уже сделал пикап в этом месяце. Любые идеи, как его реализовать?

ответ

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 имеет reserved that prefix for its own use (see Naming Stored Procedures), и вы рискуете столкнуться с именем в будущем. It's also bad for your stored procedure performance. Лучше всего просто избегать sp_ и использовать что-то еще в качестве префикса - или никакого префикса вообще!

+0

hmmm MONTH дает 1-12, не совсем то, что необходимо – Phil

+0

Но как все книги рекомендуют использовать 'sp_' в именах хранимых процедур? – Andrey

+1

@ AndreyIvanov: поделитесь хотя бы одной книгой, которая рекомендует 'sp_' как префикс хранимой процедуры? Мне было бы интересно узнать ... –

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 
+0

Спасибо! Он работает потрясающе, но если у меня есть вставка для того же клиента в том же месяце в прошлом году, он просто не вставляет :( – Andrey

+0

отметьте его как ответ, чтобы он приносил пользу другим :) –

+0

см. Мой обновленный ответ ... добавьте год. –

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.

Смежные вопросы