为什么我的 SQL Server 审核触发器会扰乱来自 Access 的 OBDC 调用/刷新?

2024-01-17

我在其中一个表上实现了一个审核触发器,它基本上将旧记录和新记录以及日期和用户复制到名为 ..._Audit 的表中。我将在下面发布我的脚本。

问题是,当我在 Access 中插入新记录然后按 Tab 进行切换时,它会刷新并显示表中的第一条记录。下面是一个例子 - 我添加了前三个记录,然后刷新,然后我添加了另外三个完全相同的数据 添加它们后,我应该看到具有相同数据和递增 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,并通过 ODBC 连接到 MS Access 2007 客户端。


正如 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% 准确的东西。

最后,我只在插入触发器上实现了这个,即使其他触发器使用插入操作。经过一些简短的测试后,这似乎没问题。我现在已将此脚本推广到所有可由普通用户编辑的表上,因此不久之后我就会知道这是否会导致问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的 SQL Server 审核触发器会扰乱来自 Access 的 OBDC 调用/刷新? 的相关文章

  • 在 MySQL 中执行触发器需要什么权限?

    我发现 MySQL 手册中对 DEFINER 的解释令人困惑 因此我不确定运行应用程序的 执行用户 需要什么权限 为了安全起见 我喜欢将 执行用户 限制为所需的最少权限 我知道触发器 存储过程的创建者需要超级权限 但是 执行用户 是否也需要
  • 是否可以将新表和旧表从触发器传递到 MySQL 中的过程中?

    是否可以将新表和旧表从触发器传递到 MySQL 中的过程中 我怀疑不会 因为没有过程接受的表这样的数据类型 有什么可能的解决方法吗 理想情况下它看起来像这样 CREATE TRIGGER Product log AFTER UPDATE O
  • 如何使用基于时间的触发器每小时运行一个脚本,仅在工作日的整点运行?

    我只需要在工作日每小时运行一个 Google App Script 脚本 两者之一似乎很容易做到 但将其结合起来我不确定 每小时触发 ScriptApp newTrigger RefreshRates timeBased inTimezon
  • IIF(...) 不是公认的内置函数

    我正在尝试在 Microsoft SQL Server 2008 R2 中使用它 SET SomeVar SomeOtherVar IIF SomeBool value when true value when false 但我收到一个错误
  • 触发器与非规范化存储过程的优缺点

    当涉及到对事务数据库中的数据进行非规范化以提高性能时 至少 有三种不同的方法 通过存储过程推送更新 更新规范化交易数据和非规范化报告 分析数据 在事务表上实现更新辅助表的触发器 这几乎总是维护历史时所采取的路线 将处理推迟到夜间批处理 可能
  • 64 位 pyodbc 是否可以与 32 位 MS Access 数据库对话?

    我正在使用 64 位 python anaconda v4 4 它运行 python v3 我有 MS Access 2016 32 位版本 我想使用 pyodbc 让 python 与 Access 对话 是否可以使用 64 位 pyod
  • 我什么时候应该创建数据库索引? [复制]

    这个问题在这里已经有答案了 何时为表设置索引 是在创建表期间还是在性能调优时 索引的优点和缺点是什么 许多 大多数 DBMS 使用索引来支持唯一约束 始终创建索引以强制执行唯一约束 它们 约束 对于数据库的正确操作至关重要 如果您可以选择如
  • PHP/PDO 和 SQL Server 连接以及 i18n 问题

    在我们的网络应用程序中 我们使用 PHP5 2 6 PDO 连接到 SQL Server 2005 数据库并存储俄语文本 数据库排序规则是Cyrillic General CI AS 表排序规则是Cyrillic General CI AS
  • SQL Server 2005 中的计数(*) 与计数(Id)

    我使用 SQLCOUNT函数获取表中的总数或行数 以下两种说法有什么区别吗 SELECT COUNT FROM Table and SELECT COUNT TableId FROM Table 另外 在性能和执行时间方面有什么区别吗 Th
  • 选择列的一部分

    我想知道是否有人可以帮助查询以选择列的一部分 criteriadata 列包含如下所示的数据 标准数据 14 27 15 14 30 15 DD 14 38 15 通过 14 33 15 通过 如何只选择数字 15 之后出现的数据 非常感谢
  • 通过 VBA MS_Access 将 MS Access 表导出为 dBase 5

    如何通过 VBA 将单个表导出为 dBase 5 文件 目前我正在使用这个VBA代码 DoCmd TransferDatabase acExport dBase IV DB Total acTable DB Total C Data Fal
  • 将 Null 与 MySQL 触发器中的另一个值进行比较

    所以这是我的问题 我在更新表行时比较新值和旧值 但新值或旧值有时会为空 所以下面的代码不起作用 我可以解决这个问题吗 谢谢 BEFORE UPDATE ON mytable FOR EACH ROW BEGIN IF OLD assigne
  • 如何在 SQL Server 2005 Management Studio 中创建 SQL Server 2005 存储过程模板?

    如何在 SQL Server 2005 Management Studio 中创建 SQL Server 2005 存储过程模板 我认为另一个小金块将帮助人们开发并提高数据库开发的效率 当我开发软件解决方案时 我非常喜欢存储过程和函数 我喜
  • SQL Server - 如何向登录名授予对所有数据库的读取访问权限?

    我需要向新登录授予对服务器上所有 300 个数据库的读取权限 如何在不选中用户映射区域中的 300 个复选框的情况下完成此操作 一种方法是在 SSMS 的查询菜单上设置 结果为文本 然后执行以下命令 它实际上并不进行更改 而是生成一个脚本供
  • 级联删除时触发调用

    我在 MySQL 中有表 A 它有一些对其他表 B C D 的级联删除的引用 当从 A 中删除某些内容时 我需要使用触发器 当我直接从 A 删除记录时 此触发器起作用 但它不适用于级联删除 是否存在任何版本的 MySQL 可以让我的触发器与
  • 选择两列中两个日期之间的记录

    如何选择两列中两个日期之间的记录 Select From MyTable Where 2009 09 25 is between ColumnDateFrom to ColumnDateTo 我有一个日期 2009 09 25 我喜欢选择
  • Google Apps 脚本触发器 - 每当将新文件添加到文件夹时运行

    我想在任何时候执行谷歌应用程序脚本new文件被添加到特定文件夹 目前 我使用的是每 x 分钟运行一次的时钟触发器 但我只需要在向文件夹添加文件时运行脚本 有没有办法做到这一点 与this https stackoverflow com qu
  • 脚本在 SpreadsheetApp.openById 上失败 - 需要权限

    我有一个 onOpen 函数 可以在电子表格中创建自定义菜单 它已经工作了一年多 但几天前它停止工作了 当我查看执行记录时 我得到 执行失败 您无权调用 SpreadsheetApp openById 所需权限 https www goog
  • 在 Oracle 中使用触发器记录对表的更改

    我的一门课有一个项目 当我们的两个表发生更改时 我们需要创建一个日志 插入 更新 删除 我们需要使用Oracle触发器和PL SQL 在日志文件中 我们需要记录用户ID 日期时间 IP地址和事件 插入 更新 删除 我知道如何设置触发器 但我
  • 更新plpgsql中触发器函数中的多列

    给出以下架构 create table account type a id SERIAL UNIQUE PRIMARY KEY some column VARCHAR create table account type b id SERIA

随机推荐

  • 将 pandas 中的多列除以另一列

    我需要将 DataFrame 中除第一列以外的所有列除以第一列 这就是我正在做的事情 但我想知道这是否不是 正确的 熊猫方式 df pd DataFrame np random rand 10 3 columns list ABC df B
  • ActiveRecord has_many 其中表 A 中的两列是表 B 中的主键

    我有一个模型 Couple 有两列 first person id and second person id和另一个模型 Person 其主键是person id并有专栏name 这是我想要的用法 including Person mode
  • 有开源的 WPF 仪表控件吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用数组设置 Excel 范围格式

    我过去曾使用变体数组来填充一系列 Excel 单元格 我想知道 有没有办法对单元格格式做同样的事情 我不想逐个单元格地进行操作 最好尽量减少获取 Excel 范围的调用次数 我主要按照兰斯的建议去做 但是 在某些情况下 我会使用我想要设置的
  • PHP Session 变量未保存

    我已经查看了有关会话变量未保存的所有问题 但没有看到我的问题 所以我要问它 我有一个表单 一旦提交 它就会在我的数据库中搜索该名称 初始表格位于第 1 页 在第 2 页上 我从第 1 页获取变量并像这样保存 searchTerm POST
  • EditText 多重编辑填充检查

    我正在创建一个项目 其中填充了 3 个编辑文本我想检查 3 个编辑文本中的任何一个是否应该填充 3 个编辑文本中的任何一个我知道如何检查所有 edittext 值中是否都有数据 private boolean validate edit1
  • MySQL 中的时间戳比日期时间列快多少?

    这包括两个问题 MySQL的时间戳字段真的比 order by 查询中的日期时间字段快吗 如果上述问题的答案是肯定的 那么速度能快多少 假设在一个有1亿行的表中 经常根据MySQL内部的时间戳字段对一堆100 200k行进行排序 排序时间的
  • 修复 Twitter Bootstrap 中的按钮大小

    I use 推特引导程序 https getbootstrap com 2 3 2 在我的网络应用程序中 我有一张有很多按钮的桌子 按钮的文本随着表行的当前状态而变化 在 Ajax 请求响应之后 我使用 Jquery 更改按钮文本 我的问题
  • Rails - 在控制器中存储 cookie 并从 Javascript、Jquery 获取

    是否可以在控制器中存储用户的 Cookie 或会话 并通过 JS 或 Jquery 访问它来获取 cookie Session值在服务器上可用 你可以这样设置它们在你的控制器中 http apidock com rails ActionCo
  • WPF - 自定义设计音量控制

    我使用 WPF 已经有一段时间了 我需要通过互联网创建以下控件 但找不到合适的 任何人都可以帮助如何实现此功能 单击控件时 值应该增加或减少 我发现我可以使用音量控制或滑块 但不清楚我应该使用什么 谢谢期待 我更喜欢使用进度条来显示此类内容
  • 如何在 Visual Studio 中添加高优先级 TODO 注释?

    添加这样的评论 TODO Refactor this code 在我可以查看的任务列表中创建一个任务等 有一列标记为 让您可以按优先级对这些任务进行排序 如何设置特定任务的优先级 任务的优先级取决于您用来标记它的关键字 您可以通过转到 工具
  • 克隆 TypeScript 对象

    我有一个打字稿课程 export class Restaurant constructor private id string private name string public getId string return this id p
  • 如何从 tmux 会话获取 stdout 和 stderr?

    我正在linux系统中编写一个示例python程序 我在用tmux https linux die net man 1 tmux创建会话并在 tmux session 中执行另一个脚本 我想将 stdout 和 stderr 从 tmux
  • Bash 复杂的管道依赖关系

    I m trying to model a build concurrent pipeline in a single Bash script I know I can use other tools but at this point I
  • OpenGL:在两个元素之间画线

    我需要在我创建的两个网格之间画一条线 每个网格都与不同的模型矩阵相关联 我一直在思考如何做到这一点 我想到了 glMatrixMode GL MODELVIEW glLoadMatrixf first object model matrix
  • iframe 将 origin 发送为 null

    我有一个 iframe 内容是从我正在使用的第三方库注入的 该库正在注入用户需要提交的表单 问题是 当表单初始化时 它们正在执行一些请求 并且标头源作为空值发送 这会导致问题 因为它们的服务器不允许空值 我尝试添加沙箱属性 甚至尝试伪造调用
  • 为什么 request.body 未定义?

    我有一个 Node js 服务器 其中包括 bodyparser 和所有内容 var express require express var dbcon require app db databaseconnection var bodyP
  • Java 相当于 .NET 的 DateTime.Parse?

    我正在开发一个 java 类 该类将与 Pervasive Data Profiler 一起使用 该类需要检查日期字符串是否适用于 NET 的 DateTime Parse 是否有等效的类或第三方库可以为我提供与 NET 的 DateTim
  • 如何从 MP3 的 URL 获取其长度?

    如果我知道 MP3 文件的 URL 获取其长度 比特率 大小等最简单 最快的方法是什么 如何仅下载 MP3 的 ID3 标签部分来获取这些详细信息 您需要查看 mp3 文件中的 ID3 标签 除非您在其他地方跟踪您想要的元数据 要专门获取文
  • 为什么我的 SQL Server 审核触发器会扰乱来自 Access 的 OBDC 调用/刷新?

    我在其中一个表上实现了一个审核触发器 它基本上将旧记录和新记录以及日期和用户复制到名为 Audit 的表中 我将在下面发布我的脚本 问题是 当我在 Access 中插入新记录然后按 Tab 进行切换时 它会刷新并显示表中的第一条记录 下面是