SQL Server 2005触发器是否可以异步执行

Novelty 2008-02-27 08:56:26
SQL Server 2005触发器Insert、Update、Delete事件是否可以异步执行。
...全文
585 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
jacson007 2009-02-18
  • 打赏
  • 举报
回复
好啊,测试下
Novelty 2008-02-28
  • 打赏
  • 举报
回复
楼上的,是根据请求的即时异步处理,所以如果sql server 2005的触发器支持异步调用就好了。
不知道sql server 2008是否支持。呵呵,期待中...
fcuandy 2008-02-27
  • 打赏
  • 举报
回复
学习一下.
Novelty 2008-02-27
  • 打赏
  • 举报
回复
比较大家的方案觉得wanyingsong的解决方案更贴近需求,先测试一下再来给分,呵呵,如果大家还有更好的方案希望继续讨论。
JiangHongTao 2008-02-27
  • 打赏
  • 举报
回复
好像可以用作业,就是在触发器中启动作业,没试过。
zefuzhang2008 2008-02-27
  • 打赏
  • 举报
回复
同意楼上答案
老宛 2008-02-27
  • 打赏
  • 举报
回复

-- 创建要使用的数据库
Create Database HelloWorldDB
go
Use HelloWorldDB
go
-- 创建要使用的两种消息类型。我们要使用的消息将是
-- 字符串而不是 XML - 因此无需进行验证
CREATE MESSAGE TYPE [HelloWorldRequest] VALIDATION = NONE
CREATE MESSAGE TYPE [HelloWorldResponse] VALIDATION = NONE

-- 创建一个限制此对话框中消息类型
-- 的规范。请求由对话框的初始化程序发出
-- 响应消息由对话框目标发送。
CREATE CONTRACT [HelloWorldContract]
(
[HelloWorldRequest] SENT BY initiator,
[HelloWorldResponse] SENT BY target
)
-- 创建对话框在其间通信的两个队列。A
-- 对话框请求两个队列。
CREATE QUEUE [HelloWorldTargetQueue]
CREATE QUEUE [HelloWorldInitiatorQueue]
-- 创建命名对话框端点的服务。服务会将
-- 会话端点连接到队列。
CREATE SERVICE [HelloWorldRequestService] ON QUEUE [HelloWorldTargetQueue]
(
[HelloWorldContract]
)
CREATE SERVICE [HelloWorldResponseService] ON QUEUE [HelloWorldInitiatorQueue]
go
现在已经设置了元数据,可以发送消息了。请注意,由于初始化程序和目标服务位于同一 SQL Server 实例中,因此消息将直接转到目标队列而不会通过传送队列传送。由于 Service Broker 内置在数据库中,因此可以进行此项性能优化。

Use HelloWorldDB
go

SET NOCOUNT ON
DECLARE @conversationHandle uniqueidentifier

Begin Transaction
-- 开始 Hello World 服务的对话

BEGIN DIALOG @conversationHandle
FROM SERVICE [HelloWorldResponseService]
TO SERVICE 'HelloWorldRequestService'
ON CONTRACT [HelloWorldContract]
WITH ENCRYPTION = OFF, LIFETIME = 600;

-- 发送消息
SEND ON CONVERSATION @conversationHandle
MESSAGE TYPE [HelloWorldRequest] (N'Hello World')

commit
让我们查看目标队列以确保成功发送了消息。

Use HelloWorldDB
go

-- 检查目标队列以确认消息已送达
select * from [HelloWorldTargetQueue]
go
-- 将消息主体转换为字符串,以便我们查看其中包含的内容
select cast(message_body as nvarchar(MAX)) from [HelloWorldTargetQueue]
go
现在可以从目标队列中接收消息并将响应发送回初始化程序。

-- 使用 Receive 命令可从队列接收消息

-- 声明变量以存储接收到的数据
SET NOCOUNT ON
DECLARE @conversationHandle uniqueidentifier
declare @message_body nvarchar(MAX)
declare @message_type_name sysname;

-- Service Broker 命令总是位于事务中
Begin Transaction;

-- Receive 命令的格式类似于一个选择列表。首先列出
-- 要获取的列,然后指定要从中获取消息
-- 的队列
RECEIVE top(1) -- 只接收一条消息,因此我们可以直接保存到变量中。
@message_type_name=message_type_name,
-- 接收的消息类型
@conversationHandle=conversation_handle,
-- 对话的标识符
-- 我们通过下列语句接收该消息
@message_body=message_body
-- 作为
-- varbinary(MAX) blob 的消息内容
FROM [HelloWorldTargetQueue]

print @message_body

-- 如果这是一条 hello world 消息,则用相应的问候语回答
if @message_type_name = N'HelloWorldRequest'
Begin
SEND ON CONVERSATION @conversationHandle
-- 使用下列消息接收语句的相同会话
MESSAGE TYPE [HelloWorldResponse]
(N'Hello From '+@@servername )
-- 这是我们希望从初始化程序接收的唯一消息,因此
-- 现在可以安全地结束对话。
END CONVERSATION @conversationHandle
End
-- 提交事务
-- 如果此时我们回滚,所有内容将退回到
-- 我们开始时的状态 – 消息会返回到队列,并且没有发送响应
Commit
go
-- 确认我们从队列中删除了消息
select cast(message_body as nvarchar(MAX)) from [HelloWorldTargetQueue]
go
响应已在对话中发送回初始化程序队列,现在检查响应是否成功到达:

Use HelloWorldDB
go

select cast(message_body as nvarchar(MAX)) from [HelloWorldInitiatorQueue]
go
... 最后接收并显示响应消息:

RECEIVE
cast(message_body as nvarchar(MAX))
FROM [HelloWorldInitiatorQueue]
老宛 2008-02-27
  • 打赏
  • 举报
回复
sql2005可以使用service broker来实现楼主想要的功能。
在触发器中往消息队列中插入,触发器完成操作。
由消息服务来异步执行。
dawugui 2008-02-27
  • 打赏
  • 举报
回复
如果真想这么搞,试试延迟函数看行不行?(DELAY)

使用 WAITFOR
WAITFOR 语句挂起执行连接,直到发生下列两种情况之一:

已超过指定的时间间隔。


到达一天中指定的时间。
WAITFOR 语句由下面两个子句之一指定:

DELAY 关键字后为 amount_of_time_to_pass,是在完成 WAITFOR 语句之前等待的时间。完成 WAITFOR 语句之前等待的时间最多为 24 小时。


TIME 关键字后为 time_to_execute,它指定 WAITFOR 语句完成的时间。
下面示例使用 DELAY 关键字指定在执行 SELECT 语句之前等待两秒:

WAITFOR DELAY '00:00:02'
SELECT EmployeeID FROM Northwind.dbo.Employees

下面示例使用 TIME 关键字指定在 10 P.M 以后对指定数据库 pubs 进行检查,以确保所有页的分配和使用正确:

USE pubs
BEGIN
WAITFOR TIME '22:00'
DBCC CHECKALLOC
END

WAITFOR 语句的缺点是与应用程序的连接一直挂起直到 WAITFOR 完成为止。当应用程序或存储过程的处理必须挂起相对有限的时间时最好使用WAITFOR。在一天中的特定时间执行某种操作较好的方法是使用 SQL Server 代理或 SQL-DMO 来调度任务。

loworth 2008-02-27
  • 打赏
  • 举报
回复
为啥要异步呢? 用事务处理不更好吗
dawugui 2008-02-27
  • 打赏
  • 举报
回复
你这个异步是啥意思.

估计你这个需求很但达到.

很难很复杂.
昵称被占用了 2008-02-27
  • 打赏
  • 举报
回复
触发器异步执行肯定是不行的,如果你的需求需要,可以考虑INSTEAD OF 触发器
qiyousyc 2008-02-27
  • 打赏
  • 举报
回复
如果确定时间的异步执行,可以用job,这样好处理。
如果执行时间不定,用消息(2005才支持)

22,298

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧