【问题标题】:Can SQL CLR triggers do this? Or is there a better way?SQL CLR 触发器可以做到这一点吗?或者,还有更好的方法?
【发布时间】:2010-09-30 08:48:08
【问题描述】:

我想编写一个监视数据库表的服务(可能在 c# 中)。当一条记录插入到表中时,我希望服务获取新插入的数据,并用它执行一些复杂的业务逻辑(对于 TSQL 来说太复杂了)。

一种选择是让服务定期检查表以查看是否已插入新记录。这样做的问题是我希望服务在插入发生时立即知道插入,并且我不想破坏数据库性能。

做一些研究,似乎编写 CLR 触发器可以完成这项工作。我可以在 c# 中编写一个在插入发生时触发的触发器,然后将新插入的数据发送到 Windows 或 WCF 服务。

您认为,SQL CLR 触发器的使用是否良好(甚至可能)?

关于如何做到这一点的任何其他想法?

【问题讨论】:

    标签: sql sql-server tsql triggers sqlclr


    【解决方案1】:

    也许您应该将后处理与插入分离:

    在插入触发器中,将记录的 PK 添加到队列表中。

    在一个单独的服务中,从队列表中读取并执行您的复杂操作。完成后,将记录标记为已处理(连同错误/状态信息),或从队列中删除记录。

    【讨论】:

    • 正是我要建议的。它将是事务安全的,并将已处理和未处理的记录保存在一个不会影响主应用程序表的表中。为这个解决方案 +1!
    • 使用 SQL Server 服务代理
    • 好主意,除了您丢失了所有已更改内容的跟踪(即删除表的内容,仅在触发器执行期间可用)。我想这取决于你需要什么。
    【解决方案2】:

    您所描述的有时称为作业队列或消息队列。您可以通过搜索找到有关使用 DBMS 表(以及其他技术)执行此操作的多个主题。

    我会考虑用触发器做任何类似的事情,因为这是对数据库功能的不当使用,无论如何都很容易遇到麻烦。触发器最适合用于低开销的 dbms 结构功能(例如细粒度的引用完整性检查),并且需要轻量级和同步。可以这样做,但可能不是一个好主意。

    【讨论】:

      【解决方案3】:

      我建议在调用SQL Server Service Broker 的表上设置一个触发器,然后(异步)执行一个 CLR 存储过程,在不同的线程中完成所有工作。

      【讨论】:

      • 同意。 .net 代码甚至不必是 clr 存储过程——它可以使用来自另一个进程的队列内容。
      【解决方案4】:

      我有一个每分钟轮询数据库的服务,它不会导致太多的性能问题,而且它是一个干净的解决方案。另外,如果您的服务或其他 wcf 端点不存在,您的触发器将失败或丢失,您将不得不在以后轮询。

      【讨论】:

        【解决方案5】:

        我不建议为此使用 CLR 触发器或任何类型的触发器。您正在向严重的可维护性和潜在的锁定问题敞开心扉。 (如果您在插入后不关心@@identity 并且您永远不会锁定审计/队列表,则可以接受将内容放入审计/队列表的非常简单的触发器)

        相反,您应该从您的应用程序/orm 触发将内容插入到队列表中,并定期处理此队列。这可以通过在您的 ORM 中进行事务或启动存储过程来完成,开始事务以原子方式提交更改和审计/队列。 (注意这里的锁定)

        如果您需要立即采取行动,请在对表执行插入/更新/删除操作后查看生成作业以清除队列并

        还要确保每分钟左右仔细检查一次队列,以防后台进程未正确启动。如果它是一个 Web 应用程序并且您想避免产生线程,您可以与后台进程通信以清除队列。

        【讨论】:

          【解决方案6】:

          为什么不在存储过程中实现插入,插入后在过程中做业务逻辑呢?有什么复杂到不能用 T-SQL 写的?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-21
            • 1970-01-01
            • 2015-11-08
            • 2011-11-11
            • 1970-01-01
            相关资源
            最近更新 更多