SEND (Transact-SQL)

适用于:SQL ServerAzure SQL 托管实例

使用一个或多个现有会话发送消息。

Transact-SQL 语法约定

语法

  
SEND  
   ON CONVERSATION [(]conversation_handle [,.. @conversation_handle_n][)]  
   [ MESSAGE TYPE message_type_name ]  
   [ ( message_body_expression ) ]  
[ ; ]  

参数

ON CONVERSATION conversation_handle [.. @conversation_handle_n]
指定消息所属的会话。 conversation_handle 必须包含一个有效的会话标识符。 不能多次使用相同的会话句柄。

MESSAGE TYPE message_type_name
指定发送的消息的消息类型。 必须将此消息类型包含在这些会话使用的服务约定中。 这些约定必须允许从此会话方发送该类型的消息。 例如,会话的目标服务只能发送在约定中指定为 SENT BY TARGET 或 SENT BY ANY 的消息。 如果省略了该从句,消息类型为 DEFAULT。

message_body_expression
提供一个表示消息主体的表达式。 Message_body_expression 是可选的。 但如果存在 message_body_expression,则表达式必须是一个可以转换为 varbinary(max) 的类型。 该表达式不能为 NULL。 如果省略该子句,则消息主体为空。

注解

重要

如果该 SEND 语句不是批处理或存储过程的第一个语句,则前一个语句必须以分号(;) 终止。

该 SEND 语句将服务在一个或多个服务代理对话的一端向这些对话另一端的服务发送消息。 RECEIVE然后该语句用于从与目标服务关联的队列中检索发送消息。

提供给 ON CONVERSATION 子句的会话句柄来自以下三个来源之一:

  • 如果发送的消息不是为了响应从另一服务收到的消息,则使用从创建此会话的 BEGIN DIALOG 语句返回的会话句柄。

  • 当发送消息是对之前从其他服务收到的消息的回复时,使用返回原始消息的 RECEIVE 语句返回的对话句号。

  • 包含该 SEND 语句的代码有时与包含BEGIN DIALOG或 RECEIVE 提供对话句柄的语句的代码是分开的。 在这种情况下,会话句柄必须是传递给包含 SEND 该语句代码的状态信息中的数据项之一。

发送到其他 SQL Server 数据库引擎实例中的服务的消息将存储在当前数据库的传输队列中,直到可以将这些消息传输到远程实例中的服务队列为止。 发送到同一数据库引擎实例中的服务的消息被直接放入与这些服务关联的队列中。 如果因出现某种情况导致无法将本地消息直接放入目标服务队列中,则可以先将本地消息存储在传输队列中,直到解决了这种情况为止。 这些事件的示例包括某些类型的错误或目标服务队列处于非活动状态。 可使用 sys.transmission_queue 系统视图查看传输队列中的消息。

SEND 是一个原子命题。 如果一个 SEND 语句在多次对话中发送消息且失败,例如对话处于错误状态,则不会有消息存储在传输队列中,也不会被放入任何目标服务队列。

Service Broker 优化在同一语句中多次对话 SEND 中发送的消息的存储和传输。

一个实例的传输队列中的消息按照以下顺序传输:

  • 与其关联的会话端点的优先级别。

  • 在优先级别内,依照它们在会话中的发送顺序。

如果 HONOR_BROKER_PRIORITY 数据库选项设置为 ON,则会话优先级中指定的优先级别仅应用于传输队列中的消息。 如果 HONOR_BROKER_PRIORITY 设置为 OFF,则会为该数据库的传输队列中的所有消息都分配默认优先级别 5。 优先级不会应用SEND到消息直接放入同一数据库引擎实例中的服务队列。

该 SEND 语句单独锁定每条发送消息的对话,以确保每次对话都按顺序送达。

SEND 在用户自定义函数中不成立。

权限

发送消息时,当前用户必须拥有 RECEIVE 所有发送消息服务队列的权限。

示例

以下示例启动一个对话,并在该对话中发送一条 XML 消息。 为了发送此消息,该示例将 xml 对象转换为 varbinary(max)

DECLARE @dialog_handle UNIQUEIDENTIFIER,
    @ExpenseReport XML;

SET @ExpenseReport = <construct message as appropriate for the application>;

BEGIN DIALOG @dialog_handle
    FROM SERVICE [//Adventure-Works.com/Expenses/ExpenseClient]
    TO SERVICE '//Adventure-Works.com/Expenses'
    ON CONTRACT [//Adventure-Works.com/Expenses/ExpenseProcessing];

SEND ON CONVERSATION @dialog_handle
    MESSAGE TYPE [//Adventure-Works.com/Expenses/SubmitExpense](@ExpenseReport);

以下示例启动三个对话,并在每个对话中发送一条 XML 消息。

DECLARE
    @dialog_handle1 UNIQUEIDENTIFIER,
    @dialog_handle2 UNIQUEIDENTIFIER,
    @dialog_handle3 UNIQUEIDENTIFIER,
    @OrderMsg XML;

SET @OrderMsg = '<construct message as appropriate for the application>';

BEGIN DIALOG @dialog_handle1
    FROM SERVICE [//InitiatorDB/InitiatorService]
    TO SERVICE '//TargetDB1/TargetService'
    ON CONTRACT [//AllDBs/OrderProcessing];

BEGIN DIALOG @dialog_handle2
    FROM SERVICE [//InitiatorDB/InitiatorService]
    TO SERVICE '//TargetDB2/TargetService'
    ON CONTRACT [//AllDBs/OrderProcessing];

BEGIN DIALOG @dialog_handle3
    FROM SERVICE [//InitiatorDB/InitiatorService]
    TO SERVICE '//TargetDB3/TargetService'
    ON CONTRACT [//AllDBs/OrderProcessing];

SEND ON CONVERSATION (
    @dialog_handle1,
    @dialog_handle2,
    @dialog_handle3
)
    MESSAGE TYPE [//AllDBs/OrderMsg](@OrderMsg); 

另请参阅

BEGIN DIALOG CONVERSATION (Transact-SQL)
END CONVERSATION (Transact-SQL)
RECEIVE (Transact-SQL)
sys.transmission_queue(Transact-SQL)