为什么我的SQL Server审核触发器搞乱了来自Access的ODBC调用/刷新?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我的SQL Server审核触发器搞乱了来自Access的ODBC调用/刷新?相关的知识,希望对你有一定的参考价值。
我在其中一个表上实现了一个审计触发器,它基本上将旧记录和新记录复制到一个名为... _ Audit的表中,以及日期和用户。我会进一步发布我的脚本。
问题是,当我在Access中插入新记录然后选项卡时,它会刷新并显示表中的第一条记录。下面是一个例子 - 我已经添加了前三个记录然后刷新,然后我添加了三个完全相同的数据添加它们之后我应该看到具有相同数据和增加ID的记录,但是他们已经抓住了第一个最后三条记录的表的三条记录。
P_SubtaskID PresetID_FK P_SubtaskName DateDay DateMonth
148 17 a new subtask 1 7
149 17 a new subtask 1 7
150 17 a new subtask 1 7
8 5 Receive, sign and save 25 10
9 5 Electronic lodgement 30 10
10 1 Review 12 7
点击刷新后,这些记录会显示它们应该显示的内容:
P_SubtaskID PresetID_FK P_SubtaskName DateDay DateMonth
148 17 a new subtask 1 7
149 17 a new subtask 1 7
150 17 a new subtask 1 7
151 17 a new subtask 25 10
152 17 a new subtask 30 10
153 17 a new subtask 12 7
这是有问题的,因为当用户添加记录然后保存它时,它显示完全不相关的记录。如果他们对此幻影进行了更改,则会影响该记录 - 这很容易导致错误更新/删除记录等。不好!
所以这是我创建审计表及其相关触发器的脚本:
USE [ClientDatabase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
DROP TABLE [dbo].[AutoTaskPresets_Subtasks_Audit]
GO
CREATE TABLE [dbo].[AutoTaskPresets_Subtasks_Audit](
SessionID int identity(1,1) not null,
[P_SubtaskID] [int] NULL,
[PresetID_FK] [int] NULL,
[P_SubtaskName] [nvarchar](255) NULL,
[DateDay] [int] NULL,
[DateMonth] [int] NULL,
[DatePeriod] [int] NULL,
[StaffName_FK] [nvarchar](255) NOT NULL,
Action nchar(10) null,
RowType nchar(10) null,
ChangedDate datetime not null default getdate(),
ChangedBy sysname not null default user_name()
)
GO
CREATE Trigger [dbo].[DeleteAutoTaskPresets_Subtasks] ON [dbo].
[AutoTaskPresets_Subtasks] FOR DELETE AS
BEGIN
SET NOCOUNT ON
INSERT dbo.AutoTaskPresets_Subtasks_Audit(
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
Action,
RowType)
SELECT
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
'Deleted',
'Old'
FROM Deleted
END
GO
CREATE Trigger [dbo].[InsertAutoTaskPresets_Subtasks]
ON [dbo].[AutoTaskPresets_Subtasks] FOR INSERT AS
BEGIN
SET NOCOUNT ON
INSERT dbo.AutoTaskPresets_Subtasks_Audit(
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
Action,
RowType)
SELECT
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
'Inserted',
'New'
FROM Inserted
END
GO
CREATE Trigger [dbo].[UpdateAutoTaskPresets_Subtasks]
ON [dbo].[AutoTaskPresets_Subtasks] FOR UPDATE AS
BEGIN
SET NOCOUNT ON
INSERT dbo.AutoTaskPresets_Subtasks_Audit(
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
[Action],
RowType)
SELECT
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
'Updated',
'Old'
FROM Deleted
INSERT dbo.AutoTAskPresets_Subtasks_Audit(
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
[Action],
RowType)
SELECT
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
'Updated',
'New'
FROM Inserted
END
GO
我很难过为什么会这样。我所能想到的可能只是一个时间问题,虽然目前触发器在我认为是优先选择的行动之后运行。
我确信这是我的触发器,因为当我删除它们时,它工作正常。我的数据库也从未显示过这样的错误。
我正在使用SQL Server 2005与MS Access 2007客户端的ODBC连接。
正如Nikola所解释的那样,该问题与@@ identity的使用有关。这将获取最后一个记录条目的标识值,因此当我执行插入时,触发器会插入到另一个表中。这导致了@@ identity的不同值,这是MS Access似乎错误依赖的。要解决这个问题,我需要在运行触发器之前保存@@ identity值,然后恢复它。如下所示,插入触发器:
CREATE Trigger [dbo].[InsertAutoTaskPresets_Subtasks]
ON [dbo].[AutoTaskPresets_Subtasks] FOR INSERT AS
BEGIN
SET NOCOUNT ON
declare @id int
set @id = @@identity
INSERT dbo.AutoTaskPresets_Subtasks_Audit(
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
Action,
RowType)
SELECT
[P_SubtaskID],
[PresetID_FK],
[P_SubtaskName],
[DateDay],
[DateMonth],
[DatePeriod],
[StaffName_FK],
'Inserted',
'New'
FROM Inserted
DECLARE @SQL varchar(8000)
SET @sql = 'SELECT IDENTITY(INT, ' + CAST(@id as varchar) + ', 1)
AS ident INTO #Tmp'
EXEC(@sql)
END
GO
令人遗憾的是,Access似乎是以这种方式构建的,依赖于不是100%准确的东西。
最后,我只在Insert触发器上实现了这一点,即使其他触发器使用插入操作。经过一些简短的测试后,这似乎没问题。我现在已经在我的所有表格上推出了这个脚本,可以由普通用户编辑,所以不久之后我就知道这是否会引起问题。
以上是关于为什么我的SQL Server审核触发器搞乱了来自Access的ODBC调用/刷新?的主要内容,如果未能解决你的问题,请参考以下文章