前段时间我问了一个关于如何使开始对话框和发送更灵活的问题,以便它可以嵌入到将 to、from 参数作为 sysname 变量的过程中。
多个发起者将使用服务代理程序开始对话对话..如何将参数传递给它
但是,正如 Rusanu 在答案中提到的,这种相同的技术不能用于 Receive 的 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
...
似乎 sysname 类型的变量不能在 RECEIVE 的 from 子句中使用?如果我必须在动态 SQL 中执行此操作,我将如何从接收函数的动态 sql 执行中返回所有变量、conversation_group_id、conversation_handle 等?有没有更好的技术来完成同样的事情?
谢谢你。
FIX/Update SO FAR:我正在创建一堆 IF 子句,具体取决于传递的参数是什么,它只会执行不同的整个接收语句。它效率不高,因为每次添加新队列时我都必须更改过程代码,但我想现在就可以了...
因为 RECEIVE 基本上是一个 DELETE 并且因此有一个查询计划,所以它必须遵守 SELECT/INSERT/DELETE/UPDATE 语句具有的相同限制,特别是它所作用的对象必须在编译时知道的限制,而不是在执行时.
唯一的选择是使用动态 SQL,随之而来的是所有的祝福和陷阱。
您还可以在项目部署期间生成过程主体,拥有一个模板并为每个队列生成一个特定的过程,专门用于特定的队列名称。这是否可行取决于许多因素,首先取决于项目的组织和部署方式。
在旁注中,我很惊讶听到你有很多队列。一般来说,趋势是有一个队列和几个队列读取器(已激活程序)。由于 SSB 编程是事件驱动的(等待消息、处理消息、等待消息、处理消息、等待消息...),因此拥有多个队列来等待消息变得更加困难,因为应用程序现在必须等待在多个源上(例如,每个队列至少一个线程)。即使使用 SSB 激活(这减轻了显式等待的需要,因为它会启动代码以按需处理消息),但多个队列也更难管理(每个队列的 max_queue_readers 加起来可能会启动太多的内部激活过程)。考虑在接收端使用单个服务和队列。即使需要多个服务(无论出于何种原因),它们也可以合并到一个队列中。
这是一个可在不同队列上重复使用的工作示例接收过程。