Триггер SQL Server при сбое процедуры - PullRequest
0 голосов
/ 14 апреля 2019

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

Моя последовательность операций в таблице выглядит следующим образом: информация о пациенте будет вставлена ​​(HISTORY_APPOINTMENTS), и если в то время пациент имеет значение столбца HasSuicidalThoughts = 'Y', я хочу, чтобы триггер отправлял вставленную информацию о пациенте в таблицу. Я создал под названием SuicideWatchLog.

Сначала я создал таблицу:

/* Table Creation for SuicideWatch Log*/
CREATE TABLE SuicideWatchLog
(
    logNum integer IDENTITY(1,1) NOT NULL PRIMARY KEY,
    PatientStudy# integer FOREIGN KEY References Patients(PatientStudy#),
    PatientName varchar(20),
    [Date] date,
    Dr# integer FOREIGN KEY References DOCTORS(Dr#),
    DaysinStudy integer
)

Далее я создал процедуру:

CREATE PROCEDURE AddSuicideWatch
    @PatientStudy# integer,
    @PatientName varchar(20),
    @Date date,
    @Dr# integer,
    @DaysinStudy integer
AS
BEGIN
    INSERT INTO SuicideWatchLog(PatientStudy#, Date, Dr#)
        (SELECT PatientStudy#, ApptDate, Dr#
         FROM APPOINTMENTS
         WHERE @PatientStudy# = PatientStudy#
           AND @Date = ApptDate
           AND @Dr# = Dr#)

    INSERT INTO SuicideWatchLog(PatientName, DaysinStudy)
        (SELECT PatientFName, datediff(day,StudyStartDate,getdate())
         FROM PATIENTS
         WHERE @PatientName = PatientFName
           AND @DaysinStudy = datediff(day,StudyStartDate,getdate()))
END

Наконец я создал триггер:

CREATE TRIGGER SuicidalPatient
ON HISTORY_APPOINTMENT
AFTER INSERT
AS
    EXEC AddSuicideWatch(
        SELECT (I.PatientStudy#, P.PatientFName, A.ApptDate,  
        FROM INSERTED I
        JOIN APPOINTMENTS A ON I.Appt# = A.Appt#
        JOIN PATIENTS P ON I.PatientStudy# = P.PatientStudy#)

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

Это проблема с оператором select или проблема с самой процедурой?

Ответы [ 2 ]

2 голосов
/ 15 апреля 2019

Это проблема с оператором select или проблема с самой процедурой?

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

1) Интегрировать вставки непосредственно в тело триггера, исключая хранимую процедуру.

2) Откройте курсор над запросом в триггере и выполните цикл по строкам, вызывая хранимую процедуру для каждого из них.

3) Объявите определяемый пользователем тип таблицы, соответствующий строкам результата запроса, объявите и загрузите экземпляр типа таблицы в теле триггера и измените хранимую процедуру, чтобы принимать параметр с табличным значением.

0 голосов
/ 15 апреля 2019

вы не можете передать таблицу в sp, но я знаю 2 пути для этого: 1 - использовать пользовательский тип, подобный этому:

create type NewTable AS table (PatientStudy# int, PatientFName nvarchar(max), ApptDate date)

и вставка в NewTable, затем вызовите sp

declare @TempTable NewTable
insert into  @TempTable(PatientStudy# , PatientFName , ApptDate)
select I.PatientStudy#, P.PatientFName, A.ApptDate,  
        FROM INSERTED I
        JOIN APPOINTMENTS A ON I.Appt# = A.Appt#
        JOIN PATIENTS P ON I.PatientStudy# = P.PatientStudy#

EXEC AddSuicideWatch( @TempTable)

и, конечно, вы должны отредактировать ваш SP:

CREATE PROCEDURE AddSuicideWatch
    @Table NewTable
AS
BEGIN
    INSERT INTO SuicideWatchLog(PatientStudy#, Date, Dr#)
        SELECT PatientStudy#, ApptDate, Dr#
         FROM APPOINTMENTS A join @Table T ON
           A.PatientStudy# = T.PatientStudy#
           A.Date = T.ApptDate
           A.Dr# = D.Dr#

    INSERT INTO SuicideWatchLog(PatientName, DaysinStudy)
        (SELECT PatientFName, datediff(day,StudyStartDate,getdate())
         FROM PATIENTS P join @Table T ON
         T.PatientName = P.PatientFName
           AND A.DaysinStudy = datediff(day,StudyStartDate,getdate()))
END

И второй способ: просто передайте первичный ключ в sp и обработайте другие вещи в sp

...