У меня есть следующий SQL-триггер, который вставляет данные в таблицу с именем PS_AUDIT_PSROLEUSR
на основе действия «Удалить», связанного с связанной таблицей.
Когда обновление таблицы инициируется онлайн-пользователем вприложение (строка роли удаляется), тогда весь OPRID вставляется правильно в PS_AUDIT_PSROLEUSR
, однако, когда триггеры запускаются через написанную мной пакетную программу, он получает только первую букву AUDIT_OPRID
.Я подтвердил это, запустив программу под другим OPRID
, и он все еще вставляет только первый символ в столбец.Простите, что я не очень хорошо знаком с триггерами SQL.
ALTER TRIGGER [dbo].[PSROLEUSER_TR]
ON [dbo].[PSROLEUSER]
FOR INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON
DECLARE @XTYPE CHAR(1), @OPRID CHAR(30)
SET @OPRID = NULL
SELECT @OPRID = CASE(CHARINDEX(',', CAST(context_info AS CHAR(128))))
WHEN 0 THEN 'Native SQL'
ELSE SUBSTRING(CAST(context_info AS CHAR(128)), 1, (CHARINDEX(',', CAST(context_info AS CHAR(128)))-1))
END
FROM sys.sysprocesses
WHERE spid = @@spid
-- Determine Transaction Type
IF EXISTS (SELECT * FROM DELETED)
BEGIN
SET @XTYPE = 'D'
END
IF EXISTS (SELECT * FROM INSERTED)
BEGIN
IF (@XTYPE = 'D')
BEGIN
SET @XTYPE = 'U'
END
ELSE
BEGIN
SET @XTYPE = 'I'
END
END
-- Transaction is a Delete
IF (@XTYPE = 'D')
BEGIN
INSERT INTO PS_AUDIT_PSROLEUSR (AUDIT_OPRID, AUDIT_STAMP, AUDIT_ACTN, ROLEUSER, ROLENAME, DYNAMIC_SW)
SELECT
@OPRID,
DATEADD(SECOND, ROW_NUMBER() OVER (ORDER BY @OPRID), GETDATE()),
'D', ROLEUSER, ROLENAME, DYNAMIC_SW
FROM
deleted
END
-- Transaction is a Insert
IF (@XTYPE = 'I')
BEGIN
INSERT INTO PS_AUDIT_PSROLEUSR (AUDIT_OPRID, AUDIT_STAMP, AUDIT_ACTN, ROLEUSER, ROLENAME, DYNAMIC_SW)
SELECT
@OPRID, GETDATE(),
'A', ROLEUSER, ROLENAME, DYNAMIC_SW
FROM
inserted
END
-- Transaction is a Update
IF (@XTYPE = 'U')
BEGIN
-- Before Update
INSERT INTO PS_AUDIT_PSROLEUSR (AUDIT_OPRID, AUDIT_STAMP, AUDIT_ACTN, ROLEUSER, ROLENAME, DYNAMIC_SW)
SELECT
@OPRID, GETDATE(), 'K',
ROLEUSER, ROLENAME, DYNAMIC_SW
FROM
deleted
-- After Update
INSERT INTO PS_AUDIT_PSROLEUSR (AUDIT_OPRID, AUDIT_STAMP, AUDIT_ACTN, ROLEUSER, ROLENAME, DYNAMIC_SW)
SELECT
@OPRID, GETDATE(), 'N',
ROLEUSER, ROLENAME, DYNAMIC_SW
FROM
inserted
END
ПРИМЕР СТРОКИ, ВСТАВЛЕННОЙ В PS_AUDIT_PSROLEUSR
AUDIT_OPRID AUDIT_STAMP AUDIT_ACTN ROLEUSER ROLENAME DYNAMIC_SW
K 2019-04-25 08:33:08.340 D LTESTUSER EUSER N
K 2019-04-25 08:33:09.340 D LTESTUSER EPRO N
Не получается получить доступ к таблице «УДАЛИТЬ»в SELECT * FROM DELETED
, поэтому я не уверен, что это просто динамически генерируется только во время выполнения.
Примечание: что странно, я запрашиваю PS_AUDIT_PSROLEUSR следующим образом для значения 'K' Iвернуть 0 строкЯ проверил, что позади буквы нет пробелов.
SELECT *
FROM PS_AUDIT_PSROLEUSR
WHERE AUDIT_OPRID = 'K'
Я получаю данные для 'K', только если использую оператор LIKE
-- Results in 0 rows
РЕДАКТИРОВАТЬ:Если я запускаю следующий код, я получаю длину 12 символов для моей строки, вставленной с «K», поэтому что-то добавляет дополнительные завершающие пробелы ...
SELECT LEN(AUDIT_OPRID),*
FROM PS_AUDIT_PSROLEUSR
WHERE AUDIT_OPRID like 'K%'
Я также попытался добавить этот простой оператор IF втриггер, однако он тоже, похоже, не работает: я думал, что преобразование двоичного файла (context_info) в varchar позволит логике отфильтровать значение «K».
IF (CONVERT(VARCHAR(256),@OPRID)) <> 'K'
BEGIN