Таблица блокировок триггеров SQL Server - PullRequest
0 голосов
/ 19 мая 2018

Я не очень разбираюсь в написании SQL, но я пытаюсь реализовать триггер после INSERT.

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

Если я запускаю оператор SELECT из SSMS, он работает, и если я запускаю его из Visual Studio в приложении VB.net, он также работает.Я попытался увеличить время ожидания команды, но оно все равно не работает.В таблице всего несколько строк данных.

Любая информация будет принята с благодарностью.Пожалуйста, дайте мне знать, если требуется более подробная информация.Это таблица часов для расчета заработной платы, которую я запускаю при вставке записи, а затем извлекаю дату окончания предыдущих дней (чтобы я мог сравнить часы расчета предыдущих дней с проектными часами предыдущих дней).

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

SELECT TOP 1
    @LastDateClockOut = datEvent
FROM 
    MyTable.dbo.TimeMTSView
WHERE 
    datEvent < @Today 
    AND strUniqueID = @nUser 
    AND blnEventType = 0 
    AND lngClassificationID = 0
ORDER BY 
    datEvent DESC;

Вот весь триггер:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[trgAfterInsert] 
ON [dbo].[tblTimes]
AFTER INSERT
AS
    DECLARE @trg_lngClassificationID int;

    SELECT @trg_lngClassificationID = i.lngClassificationID 
    FROM inserted i;

    IF (@trg_lngClassificationID = 0) --If the date Classification is 0 this means it is NORMAL time as opposed to VACATION or HOLIDAY

    DECLARE @trg_lngID int;
    DECLARE @trg_lngEmployeeID varchar(20);
    DECLARE @trg_blnEventType bit;
    DECLARE @blnEventChar nvarchar(1);
    DECLARE @trg_datEvent datetime;
    DECLARE @nUser varchar(255);
    DECLARE @cmd varchar(255);
    DECLARE @Today varchar(255);
    DECLARE @LastDateClockOut datetime;
    DECLARE @strLastClock varchar(255);

    SELECT @trg_lngID = i.lngID FROM inserted i;
    SELECT @trg_lngEmployeeID = i.lngEmployeeID FROM inserted i;
    SELECT @trg_blnEventType = i.blnEventType FROM inserted i;
    SELECT @trg_datEvent = i.datEvent FROM inserted i;

    SELECT @nUser = strUniqueID 
    FROM dbo.tblEmployees 
    WHERE lngID = @trg_lngEmployeeID AND blnDeleted = 0

    SELECT @blnEventChar = CONVERT(NVARCHAR, @trg_blnEventType);
    SELECT @Today = CONVERT(VARCHAR, GetDate(), 103);

    SELECT TOP 1 @LastDateClockOut = datEvent 
    FROM MyTable.dbo.TimeMTSView 
    WHERE datEvent < @Today 
      AND strUniqueID = @nUser 
      AND blnEventType = 0 
      AND lngClassificationID = 0 
    ORDER BY datEvent DESC --This is what fails

    SELECT @strLastClock = CONVERT(VARCHAR, @LastDateClockOut, 103);

    -- Grab the path to the TimeMTSTrigger.exe written out by the application itself to a log file:
    DECLARE @FileContents  VARCHAR(MAX)

    SELECT @FileContents = BulkColumn
    FROM OPENROWSET(BULK'C:\MTSPath\MTSPath.sql', SINGLE_BLOB) x;

    SET @cmd = 'Start ' + @FileContents + ' ' + @nUser + ' ' + @blnEventChar + ' ' + @strLastClock
    EXEC xp_cmdshell @cmd

1 Ответ

0 голосов
/ 19 мая 2018

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

Представление объединило две таблицы из базы данных TIMECLOCKMTS, чтобы упростить сбор данных,Однако оператор SELECT в представлении не будет выполняться в триггере SQL или в самом exe-файле, он будет зависать и вызывать тайм-аут.

Удаляя представление из Trigger и EXE, и ссылаясь только на таблицы в базе данных Trigger.это работает отлично:

USE [TIMECLOCKMTS]
GO
/****** Object:  Trigger [dbo].[trgAfterInsert]    Script Date: 5/19/2018 2:22:34 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[trgAfterInsert] ON [dbo].[tblTimes]
AFTER INSERT
AS

declare @trg_lngClassificationID int;
SELECT @trg_lngClassificationID=i.lngClassificationID from inserted i;

IF (@trg_lngClassificationID = 0) --If the date Classification is 0 this means it is NORMAL time as opposed to VACATION or HOLIDAY
declare @trg_lngID int;
declare @trg_lngEmployeeID varchar(20);
declare @trg_blnEventType bit;
declare @blnEventChar nvarchar(1);
declare @trg_datEvent datetime;
declare @nUser varchar(255);
declare @cmd varchar(255);
declare @Today varchar(255);
declare @LastDateClockOut datetime;

SELECT @trg_lngID=i.lngID from inserted i;
SELECT @trg_lngEmployeeID=i.lngEmployeeID from inserted i;
SELECT @trg_blnEventType=i.blnEventType from inserted i;
SELECT @trg_datEvent=i.datEvent from inserted i;
SELECT @nUser = strUniqueID FROM dbo.tblEmployees WHERE lngID = @trg_lngEmployeeID AND blnDeleted = 0
SELECT @blnEventChar = CONVERT(NVARCHAR, @trg_blnEventType);

--Grab the path to the TimeMTSTrigger.exe written out by the application itself to a log file:
DECLARE @FileContents  VARCHAR(MAX)
SELECT @FileContents=BulkColumn
FROM   OPENROWSET(BULK'C:\MTSPath\MTSPath.sql',SINGLE_BLOB) x;

SET @cmd = 'Start ' + @FileContents + ' ' + @nUser + ' ' + @blnEventChar + ' ' + @trg_lngEmployeeID
EXEC xp_cmdshell @cmd
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...