我不太擅长编写SQL,但是我试图在INSERT之后实现一个触发器。
触发器将触发,但是,这个特定的SELECT
语句变得越复杂,它似乎锁定了表。如果我简化语句只有几个参数它运行正常。
如果我从SSMS运行SELECT
语句,它可以工作,如果我在VB.net应用程序中从Visual Studio运行它,它也可以工作。我尝试过增加命令超时但仍然失败。表中只有几行数据。
非常感谢任何见解。如果需要更多细节,请告诉我。这是一个工资单时钟表,我在插入记录时触发,然后抓住前几天的时钟输出日期(这样我就可以比较前几天的工资单小时数和前几天的工作时间)。
我忘了提到我在我创建的视图上运行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
答案 0 :(得分:0)
我能够通过不在我在单独数据库中创建的View上运行SELECT语句来解决这个问题。
View结合了TIMECLOCKMTS数据库中的两个表,以便更轻松地获取数据。但是,View上的SELECT语句不能在SQL Trigger或exe本身中运行,它们都会挂起并超时。
通过从Trigger和EXE中删除View并仅在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