AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 19152
Accepted
fa1c0n3r
fa1c0n3r
Asked: 2012-06-13 16:34:22 +0800 CST2012-06-13 16:34:22 +0800 CST 2012-06-13 16:34:22 +0800 CST

如何使灵活的服务代理在存储的 sql 过程中接收,如何将“FROM”参数传递给接收

  • 772

前段时间我问了一个关于如何使开始对话框和发送更灵活的问题,以便它可以嵌入到将 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 子句,具体取决于传递的参数是什么,它只会执行不同的整个接收语句。它效率不高,因为每次添加新队列时我都必须更改过程代码,但我想现在就可以了...

sql-server sql-server-2008
  • 2 2 个回答
  • 6515 Views

2 个回答

  • Voted
  1. Best Answer
    Remus Rusanu
    2012-06-13T21:02:36+08:002012-06-13T21:02:36+08:00

    因为 RECEIVE 基本上是一个 DELETE 并且因此有一个查询计划,所以它必须遵守 SELECT/INSERT/DELETE/UPDATE 语句具有的相同限制,特别是它所作用的对象必须在编译时知道的限制,而不是在执行时.

    唯一的选择是使用动态 SQL,随之而来的是所有的祝福和陷阱。

    您还可以在项目部署期间生成过程主体,拥有一个模板并为每个队列生成一个特定的过程,专门用于特定的队列名称。这是否可行取决于许多因素,首先取决于项目的组织和部署方式。

    在旁注中,我很惊讶听到你有很多队列。一般来说,趋势是有一个队列和几个队列读取器(已激活程序)。由于 SSB 编程是事件驱动的(等待消息、处理消息、等待消息、处理消息、等待消息...),因此拥有多个队列来等待消息变得更加困难,因为应用程序现在必须等待在多个源上(例如,每个队列至少一个线程)。即使使用 SSB 激活(这减轻了显式等待的需要,因为它会启动代码以按需处理消息),但多个队列也更难管理(每个队列的 max_queue_readers 加起来可能会启动太多的内部激活过程)。考虑在接收端使用单个服务和队列。即使需要多个服务(无论出于何种原因),它们也可以合并到一个队列中。

    • 5
  2. Andre Booysen
    2013-04-02T04:17:25+08:002013-04-02T04:17:25+08:00

    这是一个可在不同队列上重复使用的工作示例接收过程。

    ALTER PROCEDURE [dbo].[zBroker_OnReceive_WFItemsUpdated_Queue]
    AS
    BEGIN
                    SET NOCOUNT ON;
    
                    DECLARE @h UNIQUEIDENTIFIER;
                    DECLARE @messageType int;
                    DECLARE @Packet VARCHAR(50);
                    DECLARE @MyId UNIQUEIDENTIFIER;
                    DECLARE @QueueName NVARCHAR(200);
                    DECLARE @Sql NVARCHAR(2000);
    
                    SET  @MyId = NEWID(); -- Just an Id for testing that get's written to the log table
    
                    SET @QueueName = (
                                    SELECT q.NAME
                                    FROM                                
                                                    sys.service_queues q (nolock)
                                    JOIN                
                                                    sys.dm_broker_activated_tasks t (nolock) ON t.spid = @@SPID AND q.object_id = t.queue_id
                    )   
                    SET @Sql = 'WAITFOR( RECEIVE TOP(1) 
                                                    @h = conversation_handle,
                                                    @messageType = message_type_id,
                                                    @Packet = message_body
                                                    FROM ' + @QueueName + '), TIMEOUT 1000;'
    
                    --Clear the queue
                    WHILE (1=1)
                 BEGIN
                                    BEGIN TRANSACTION;
    
                                 EXECUTE sp_executesql @Sql
                                    ,N'@h UNIQUEIDENTIFIER OUTPUT,@messageType int OUTPUT,@Packet VARCHAR(50) OUTPUT'
                                    ,@h = @h OUTPUT
                                    ,@messageType = @messageType OUTPUT
                                    ,@Packet = @Packet OUTPUT
    
    
                                    IF (@@ROWCOUNT = 0)
                                    BEGIN
                                                    COMMIT;
                                                  BREAK;
                                    END
                                    ELSE
                                    BEGIN
    
                                                    IF  @messageType <= 2  
                                                    BEGIN
                                                                    END CONVERSATION @h;
                                                    END
                                                ELSE 
                                                    BEGIN
    
                                                                    INSERT  INTO t_log (logdata,msgdata,ProcId,StartTime)
                                                                    VALUES  ( @QueueName, @Packet ,@MyId,GETDATE());
    
                                                                    WAITFOR DELAY '00:00:10';
                                                                    UPDATE t_log SET EndTime = GETDATE()
                                                                    WHERE logid = @@identity
    
                                                                    END CONVERSATION @h;
                                                END                             
    
                                                COMMIT;
                                    END
                END
    END
    
    • 3

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 如何确定是否需要或需要索引

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve