SQL Server: задание SQL запускается один раз в день. Если запустить более одного раза, это приведет к ошибке не может вставить дубликат ключа в объект - PullRequest
0 голосов
/ 02 октября 2019

Я уже писал этот вопрос: SQL Server: Использование курсора для циклического добавления и вставки инкрементных значений (спасибо тем, кто дает мне решения)

Поэтому я создаю запрос как сохраненныйпроцедура, и она будет выполняться ежедневно. Вот оно:

 CREATE PROC [dbo].[sp_est_busrequest]
 As
 declare @ReqDocNo  int = 0;

 set nocount on

 Select  @ReqDocNo = isnull(convert(int, max(ReqDocNo)), 0) 
 from    est_Request;

 insert  into est_Request (ReqDocNo,Reason,PickUpDate,PickUpTime,SendBackDate,SendBackTime,Requester,DeptID,Ext,RequestDate,RequestTime,ApprovedBy,ApprovedDate,Remark1,Remark2,Status )
 select  Distinct ReqDocNo = right('0000000000' 
                    + convert(varchar(10), 
                              @ReqDocNo + dense_rank() over (order by ot.pick_up_date, ot.shift_time)), 
                     10),
    '', pick_up_date ,shift_time , send_back_date, send_back_time ,pic,'',ext,convert(date, getdate()), convert(time, getdate()),'','','','',UPPER(status)
    FROM   ot

    insert into est_RequestDetail
    Select ReqDocNo = right('0000000000' 
                    + convert(varchar(10),  
                              @ReqDocNo + dense_rank() over (order by ot.pick_up_date, ot.shift_time)), 
                     10), ot.empid, RouteNo,BusStopID,'',''  
      from est_BusGuest , ot   
      where est_BusGuest.empid = ot.empid  
      and   routeNo in (select routeno from est_busroute a, est_buszone b  
                          where a.zoneno = b.zoneno  
                          and   b.branchid = '2') 

set nocount off

truncate table ot  

таблица не должна усекаться, потому что она будет ежедневно получать данные из другой системы.

таблица est_Request и est_RequestDetail имеет индекс и первичный ключ. Вот информация для индекса:

 Index description for table est_Request:  
 PK_est_Request | nonclustered, unique, primary key located on PRIMARY | ReqDocNo 
 Request_ix1 | clustered, unique located on PRIMARY | ReqDocNo, PickUpDate, SendBackDate  

 Index description for table est_RequestDetail:  
 PK_est_RequestDetail | nonclustered, unique, primary key located on PRIMARY | ReqDocNo, empID 
 Request_ix1 | clustered located on PRIMARY | ReqDocNo  
 Request_ix2 | nonclustered located on PRIMARY | ReqDocNo, empID

Так что, если задание SQL запускается один раз в день, данные будут вставлены успешно и без ошибок. Тем не менее, я беспокоюсь, если есть необходимость запускать задание SQL более одного раза в день, возможно, есть ошибка с данными, которые требуют ручного запуска задания, что приведет к дублированию ошибки. У меня вопрос, это правильный способ сделать, или мне нужно изменить структуру таблицы, как удалить индекс.

1 Ответ

1 голос
/ 02 октября 2019

ваш скрипт в порядке, но вам не нужно дублировать генерацию ReqDocNo во время вставки основной таблицы и таблицы сведений. вот что я бы посоветовал, используя cte как хранилище ваших сгенерированных ReqDocNo

declare @ReqDocNoTb table(
        ReqDocNo varchar(50),
        EmpId int
);

with cte as (
    select  distinct ReqDocNo = right('0000000000' 
                    + convert(varchar(10), 
                              (select isnull(convert(int, max(ReqDocNo)), 0) from est_Request) + dense_rank() over (order by ot.pick_up_date, ot.shift_time)), 
                     10) as ReqDocNo,
                    EmpId    
    from ot
)
insert into @ReqDocNoTb(ReqDocNo, EmpId)
select ReqDocNo, EmpId from cte

--uncomment to check generated RecDocNo before inserting
--select * from @ReqDocNoTb 

insert into est_Request (ReqDocNo,Reason,PickUpDate,PickUpTime,SendBackDate,SendBackTime,Requester,DeptID,Ext,RequestDate,RequestTime,ApprovedBy,ApprovedDate,Remark1,Remark2,Status)
select c.ReqDocNo,'', pick_up_date ,shift_time , send_back_date, send_back_time ,pic,'',ext,convert(date, getdate()), convert(time, getdate()),'','','','',UPPER(status) from @ReqDocNoTb c
    inner join ot o on o.EmpId = c.EmpId

insert into est_RequestDetail
select c.ReqDocNo, c.empid, b.RouteNo, b.BusStopID,'',''  
from est_BusGuest b, @ReqDocNoTb c   
      where est_BusGuest.empid = c.empid  
      and   routeNo in (select routeno from est_busroute a, est_buszone b  
                          where a.zoneno = b.zoneno  
                          and   b.branchid = '2') 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...