2013-05-08 4 views
0

Я запускаю веб-сайт с использованием SQL Server 2008 и ASP.NET 4.0. Я пытаюсь проследить проблему, что моя хранимая процедура создает дубликаты записей за ту же дату. Первоначально я думал, что это может быть проблема с паролем, но дубликаты записывают ту же дату до миллисекунд. Один из дубликатов: «2013-04-26 15: 48: 28.323« Все данные точно такие же, кроме идентификатора.Сохраненная процедура SQL Server Создание дубликатов

@check_date является входом в хранимую процедуру, которая дает нам определенную дату мы рассматриваем (записи являются горничной ежедневно)

@formHeaderId хватают ранее в хранимой процедуре, получение заголовка ID, как это подробно таблица с отношением 1 к многим с заголовком.

Запись @getdate() - это то, где я нашел повторяющиеся записи, есть записи с точными значениями getdate() для разных строк.

Это не происходит с каждой записью, она случайно встречается в приложении.

select @formHeaderId=stage2_checklist_header_id 
from stage2_checklist_header 
where [email protected] 
and [email protected]_month 
order by start_date desc 

if @formHeaderId = 0 begin 

    insert into stage2_checklist_header(
     environmental_forms_id  
     ,start_date 
     ,checklist_monthyear 
     ,st2h_load_date) 
    values(@envFormId 
      ,@check_date 
      ,@inspected_month 
      ,getdate()) 

    set @formHeaderId = scope_identity() 
    print 'inserted new header record ' + cast(@formHeaderId as varchar(50)) 

end 

IF (NOT EXISTS(
     SELECT * 
     FROM stage2_checklist_detail 
     WHERE stage2_checklist_header_id = @formHeaderId 
      AND check_date = @check_date 
    )) 
INSERT INTO stage2_checklist_detail 
    (stage2_checklist_header_id, check_date, st2_chk_det_load_date, 
    inspected_by) 
VALUES 
    (@formHeaderId, @check_date, GETDATE(), @inspected_by) 

SET @form_detail_id = SCOPE_IDENTITY() 
    PRINT 'inserted detail record ' + CAST(@form_detail_id AS VARCHAR(50)) 
+0

У вас есть триггер, связанный с этим sp? – scc

+4

«Все данные точно такие же, кроме идентификатора». В вашей проверке вы ищете соответствующий идентификатор. Если он отличается от другого, то строка будет вставлена. –

+1

Трудно увидеть потенциал дублирующей вставки в этом разделе кода. Возможно ли, что два потока вашего кода приложения выполняют эту процедуру одновременно? Возможно, они ударят по той же миллисекунде. Или внутри цикла есть цикл? – criticalfix

ответ

0

Вот similar case где разработчик был в состоянии отслеживать повторяющиеся записи для одновременных вызовов из разного ИСПА (который уклонился от EXISTS чека). После экспериментов с уровнями изоляции и транзакциями, а также для предотвращения взаимоблокировок, похоже, что решение в этом случае должно было использовать sp_getapplock и sp_releaseapplock.

0

В проверке NOT EXISTS вы ищете записи, имеющие одинаковый идентификатор и ту же дату. Итак, если комбинация ID AND date не существует в таблице, строка будет вставлена. В описании проблемы вы указываете: «Все данные точно такие же, кроме идентификатора». Идентификатор, отличающийся, всегда вызывает INSERT на основе логики, которую вы используете, чтобы проверить наличие.

+0

. Я думаю, что OP говорит о stage2_checklist_detail_id, а не stage2_checklist_header_id. В этом разделе кода мы видим только переменные (at) form_detail_id и (at) formHeaderId. – criticalfix

+0

Да, это правильно. В заявлении говорилось, что «все данные, за исключением stage2_checklist_detail_id, одинаковы». stage2_checklist_detail_id - это поле первичного ключа с автоматическим приращением, которое генерируется при вставке. Если в таблице уже есть stage2_checklist_header_id и check_date, она не должна вставлять другую строку. – shenn