ОШИБКА сбоя запланированного задания: [SQLSTATE 42000] (ошибка 7344)

#sql-server #error-handling #jobs #sql-job

#sql-сервер #обработка ошибок #Вакансии #sql-задание

Вопрос:

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

Выполняется от имени пользователя: EBGROUP svc_denue6dscl003_sq. Поставщик OLE DB «MSDASQL» для связанного сервера «DEERDS09» не смог ОБНОВИТЬ таблицу «[MSDASQL]» из-за столбца «austrittsdatum». Значение данных нарушило ограничения целостности для столбца. [SQLSTATE 42000] (Ошибка 7344) Поставщик OLE DB «MSDASQL» для связанного сервера «DEERDS09» вернул сообщение «Столбец, не имеющий значения null, не может быть обновлен до Null.». [SQLSTATE 01000] (ошибка 7412). Сбой шага.

Это задание состоит из трех шагов, и первые два успешно выполняются, но каждый раз на 3-м шаге (указано ниже) при обновлении происходит сбой.

 WITH DEPARTURES as (
    SELECT * FROM OPENQUERY(DEERDSXX, ''SELECT * FROM neue_ma.AustretendeMA ;'')
), PERSON as (
    SELECT PERSNR_WR, AUSTRITT_WR, weblogin_WR,KUENDDATZU_WR 
    FROM [DATEV_DBENGINE].[DENUE6ASXXXWINDVSW1DATEVDATENPMSDATENBANKENWIS32DATEVDB].dbo.PERSON 
    WHERE DBACCOUNT = 40 AND PK > 0
)
, JOINPERSNMT as (
SELECT lfdnr, ma_uid, name, vorname, login, letztertag, austrittsdatum, confirmed
, convert(date,Austritt_WR) as Austritt_wr
, convert(date,isnull(KUENDDATZU_WR, Austritt_wr)) as ITDeactivation
, CAST(RIGHT(RTRIM(LTRIM(PERSNR_WR)), 6) as INT) as PERNR
,ISNULL(DATEADD(HOUR, 36, AUSTRITT_WR), CAST(''29991231'' as DATETIME)) as flagdate
,  CASE WHEN SYSDATETIME() >= ISNULL(DATEADD(HOUR, 36, AUSTRITT_WR), CAST(''29991231'' as DATETIME)) THEN 10 else 0 end as confirmed_now
FROM DEPARTURES
LEFT OUTER JOIN PERSON
on person.weblogin_WR=DEPARTURES.Login)
update DEPARTURES set 
DEPARTURES.confirmed=case  confirmed_now when 10 then confirmed_now else DEPARTURES.confirmed end  -- only update when confirmed now
, DEPARTURES.ma_status=case  confirmed_now when 10 then 8 else DEPARTURES.ma_status end  -- only update when confirmed now
, DEPARTURES.austrittsdatum=JOINPERSNMT.Austritt_wr
, DEPARTURES.letztertag=JOINPERSNMT.ITDeactivation
from JOINPERSNMT 
where 
(JOINPERSNMT.Austritt_wr<>DEPARTURES.austrittsdatum or JOINPERSNMT.ITDeactivation<>DEPARTURES.letztertag 
or (JOINPERSNMT.confirmed_now=10 and JOINPERSNMT.confirmed_now<>JOINPERSNMT.confirmed)
) 
and DEPARTURES.ma_uid=JOINPERSNMT.ma_uid and DEPARTURES.login=JOINPERSNMT.LOGIN;'
 

Я проверил столбец ‘austrittsdatum’, который не имеет нулевых значений, также проверил Austritt_wr, который имеет нулевые значения, но это дата ухода, и у сотрудников, которые все еще находятся в организации, у них не будет даты ухода. Он работал без сбоев до вчерашнего вечера. Каким будет RC?

Ответ №1:

Я проверил логику обновления без обновления столбцов

 WITH DEPARTURES as (
    SELECT * FROM OPENQUERY(DEERDS09, 'SELECT * FROM neue_ma.AustretendeMA ;')
), PERSON as (
    SELECT PERSNR_WR, AUSTRITT_WR, weblogin_WR,KUENDDATZU_WR 
    FROM [DATEV_DBENGINE].[DENUE6AS069WINDVSW1DATEVDATENPMSDATENBANKENWIS32DATEVDB].dbo.PERSON 
    WHERE DBACCOUNT = 40 AND PK > 0
)
SELECT DEPARTURES.lfdnr, DEPARTURES.ma_uid, DEPARTURES.name, DEPARTURES.vorname, DEPARTURES.login, DEPARTURES.letztertag, DEPARTURES.austrittsdatum, DEPARTURES.confirmed
, convert(date,PERSON.Austritt_WR) as Austritt_wr
, convert(date,isnull(PERSON.KUENDDATZU_WR, PERSON.Austritt_wr)) as ITDeactivation
, CAST(RIGHT(RTRIM(LTRIM(PERSON.PERSNR_WR)), 6) as INT) as PERNR
,ISNULL(DATEADD(HOUR, 36, PERSON.AUSTRITT_WR), CAST('29991231' as DATETIME)) as flagdate
,  CASE WHEN SYSDATETIME() >= ISNULL(DATEADD(HOUR, 36, PERSON.AUSTRITT_WR), CAST('29991231' as DATETIME)) THEN 10 else 0 end as confirmed_now
FROM DEPARTURES
LEFT OUTER JOIN PERSON
on person.weblogin_WR=DEPARTURES.Login
where 
(PERSON.Austritt_wr<>DEPARTURES.austrittsdatum or convert(date,isnull(PERSON.KUENDDATZU_WR, PERSON.Austritt_wr))<>DEPARTURES.letztertag 
or (CASE WHEN SYSDATETIME() >= ISNULL(DATEADD(HOUR, 36, PERSON.AUSTRITT_WR), CAST('29991231' as DATETIME)) THEN 10 else 0 end=10 and 
CASE WHEN SYSDATETIME() >= ISNULL(DATEADD(HOUR, 36, PERSON.AUSTRITT_WR), CAST('29991231' as DATETIME)) THEN 10 else 0 end<>confirmed)
) 
and DEPARTURES.ma_uid=ma_uid and DEPARTURES.login=LOGIN;
 

Он возвращает одно значение, для которого Austritt_wr равно НУЛЮ, но KUENDDATZU_WR имеет действительную дату. Что не соответствует бизнес-логике.