fa1*_*n3r 4 sql-server-2008 sql-server dynamic-sql service-broker
不久前,我问了一个关于如何使开始对话框和发送更灵活的问题,以便它可以嵌入到将 to、from 参数作为 sysname 变量的过程中。
多个发起者将使用的服务代理程序开始对话对话..如何将参数传递给它
然而,正如 Rusanu 在回答中提到的,同样的技术不能用于接收的 From 子句。
实际上它会起作用。大多数 SSB 动词都接受参数作为参数(当然,RECEIVE 的队列名称除外)。参数的类型为 sysname ...
实际上发送方已经完成,我现在试图以同样的方式使接收变得灵活,例如:
CREATE PROCEDURE QueueReceive
@myTargetQueue SYSNAME
@cg UNIQUEIDENTIFIER OUTPUT
@ch UNIQUEIDENTIFIER OUTPUT
@msg XML OUTPUT
as
BEGIN TRANSACTION;
WAITFOR
( RECEIVE TOP(1)
@cg = conversation_group_id,
@msg = cast(message_body as XML),
@ch= conversation_handle
FROM @myTargetQueue
), TIMEOUT 3000;
COMMIT
...
Run Code Online (Sandbox Code Playgroud)
似乎不能在 RECEIVE 的 from 子句中使用 sysname 类型的变量?如果我必须在动态 SQL 中执行此操作,我将如何从接收函数的动态 sql 执行中返回所有变量、conversation_group_id、conversation_handle 等?有没有更好的技术来完成同样的事情?
谢谢你。
修复/更新到目前为止:我正在创建一堆 IF 子句,具体取决于传递的参数是什么,它只会执行不同的整个接收语句。它效率不高,因为我每次添加新 QUEUE 时都必须更改过程代码,但我想现在可以了...
因为 RECEIVE 基本上是一个 DELETE 并且因此有一个查询计划,它必须遵守 SELECT/INSERT/DELETE/UPDATE 语句具有的相同限制,特别是它所作用的对象的限制必须在编译时知道,而不是在执行时.
唯一的选择是使用动态 SQL,以及随之而来的所有祝福和陷阱。
您还可以在项目部署期间生成过程主体,拥有一个模板并为每个队列生成一个特定的过程,专用于特定的队列名称。这是否可行取决于许多因素,首先取决于您的项目组织和部署方式。
顺便说一句,我很惊讶听到你有很多队列。一般来说,趋势是有一个队列和几个队列阅读器(激活程序)。由于 SSB 编程是事件驱动的(等待消息、处理消息、等待消息、处理消息、等待消息……)有多个队列来等待消息变得更加困难,因为应用程序现在必须等待在多个来源上(例如,每个队列至少一个线程)。即使使用 SSB 激活,这减轻了显式等待的需要,因为它启动代码来按需处理消息,多个队列也更难管理(每个队列的 max_queue_readers 加起来可能会启动太多的内部激活过程)。考虑在接收端使用单个服务和队列。即使需要多个服务(无论出于何种原因),它们也可以合并到一个队列中。