RECEIVE (Transact-SQL)

從佇列中擷取一或多則訊息。根據佇列的保留設定,從佇列中移除訊息或更新佇列中的訊息狀態。

語法

[ WAITFOR ( ]
    RECEIVE [ TOP ( n ) ] 
        <column_specifier> [ ,...n ]
        FROM <queue>
        [ INTO table_variable ]
        [ WHERE {  conversation_handle = conversation_handle
                 | conversation_group_id = conversation_group_id } ]
[ ) ] [ , TIMEOUT timeout ]
[ ; ]

<column_specifier> ::=
{    * 
  |  { column_name | [ ] expression } [ [ AS ] column_alias ]
  |  column_alias = expression 
}     [ ,...n ] 

<queue> ::=
{
    [ database_name . [ schema_name ] . | schema_name . ]
        queue_name
}

引數

  • WAITFOR
    指定如果目前沒有訊息,RECEIVE 陳述式便等待訊息到達佇列。
  • TOP( n )
    指定要傳回的最大訊息數目。如果未指定這個子句,便會傳回符合陳述式準則的所有訊息。
  • *
    指定結果集包含佇列中的所有資料行。
  • column_name
    這是結果集所要包含的資料行名稱。
  • expression
    這是一個資料行名稱、常數、函數,或任何由運算子連接的資料行名稱、常數和函數之組合。
  • column_alias
    這是取代結果集中之資料行名稱的替代名稱。
  • FROM
    指定要擷取的訊息所在的佇列。
  • database_name
    這是包含要接收的訊息所在之佇列的資料庫名稱。若未提供 database_name,預設為目前的資料庫。
  • schema_name
    這是擁有要接收的訊息所在之佇列的結構描述名稱。若未提供 schema_name,預設為目前使用者的預設結構描述。
  • queue_name
    這是要接收的訊息所在之佇列的名稱。
  • INTO table_variable
    指定要從接收的訊息中選取放入資料行的資料表。
  • WHERE
    指定所接收之訊息的交談或交談群組。如果忽略這個值,便從下一個可用的交談群組傳回訊息。
  • conversation_handle = conversation_handle
    指定所接收之訊息的交談。提供的 conversation_handle 必須是 uniqueidentifer,或可轉換為 uniqueidentifier 的類型。
  • conversation_group_id = conversation_group_id
    指定接收的訊息之交談群組。提供的 conversation_group_id 必須是 uniqueidentifier,或可轉換為 uniqueidentifier 的類型。
  • TIMEOUT timeout
    指定陳述式等候訊息的時間 (以毫秒為單位)。這個子句只適用於 WAITFOR 子句。如果未指定這個子句,或逾時為 -1,等候時間便沒有限制。如果等候時間逾時,RECEIVE 會傳回空的結果集。

備註

ms186963.note(zh-tw,SQL.90).gif重要事項:
如果 RECEIVE 陳述式不是批次或預存程序中的第一個陳述式,就必須利用 Transact-SQL 陳述式結束字元分號 (;) 來終止前一個陳述式。

RECEIVE 陳述式會從佇列中讀取訊息並傳回結果集。傳回的結果集是由零或多個資料列組成,每個資料列都包含一則訊息。如果未使用 INTO 子句,且 column_specifier 未指派本機變數值,陳述式會將結果集傳回給發出呼叫的程式。

除非佇列指定保留訊息,否則,RECEIVE 陳述式會從佇列中移除接收的訊息。當佇列的 RETENTION 設定是 ON 時,RECEIVE 陳述式會將狀態資料行更新為 1,並將訊息保留在佇列中。當包含 RECEIVE 陳述式的交易回復時,也會回復交易內的所有佇列變更,且會將訊息傳回給佇列。

RECEIVE 陳述式傳回的所有訊息都屬於相同的交談群組。RECEIVE 陳述式會鎖定傳回訊息的交談群組,直到包含陳述式的交易完成為止。RECEIVE 陳述式傳回的結果集會隱含地排序。對於給定的交談,RECEIVE 陳述式以遞增 message_sequence_number 的順序,傳回狀態1 的訊息。

RECEIVE 陳述式的 WHERE 子句只能包含使用 conversation_handleconversation_group_id 的搜尋條件。搜尋條件不能包含佇列中的任何其他資料行。conversation_handleconversation_group_id 不能是運算式。當未指定 WHERE 子句時,不論目前連接在其他交談群組上保存任何鎖定,RECEIVE 陳述式都會從下一個可用的交談群組傳回訊息。當 WHERE 子句未指定 conversation_handle 時,不論每則訊息是屬於哪個交談,RECEIVE 陳述式都會從交談群組傳回訊息。如果 WHERE 子句中指定的交談控制代碼或交談群組識別碼不存在,或與指定的佇列沒有關聯,RECEIVE 陳述式便會傳回錯誤。

如果 RECEIVE 陳述式中指定的佇列,其佇列狀態設為 OFF,陳述式將會因 Transact-SQL 錯誤而失敗。

當指定 WAITFOR 子句時,陳述式會等候指定的逾時,或等候可用的結果集。如果陳述式正在等候時,佇列被卸除或佇列狀態設為 OFF,陳述式會立即傳回錯誤。如果 RECEIVE 陳述式指定交談群組或交談控制代碼,且這項交談的服務被卸除或移至另一個佇列,RECEIVE 陳述式會報告發生 Transact-SQL 錯誤。

RECEIVE 在使用者自訂函數中無效。

下表列出佇列中的資料行。

資料行名稱 資料類型 描述

status

tinyint

訊息狀態。對於 RECEIVE 命令傳回的訊息而言,狀態一律是 0。佇列中的訊息可包含下列各值之一:

0=備妥1=接收的訊息2=尚未完成3=保留的傳送訊息

priority

tinyint

0. 警告僅做為識別目的。不支援。我們無法保證未來的相容性。.

queuing_order

bigint

佇列中的訊息順序號碼。

conversation_group_id

uniqueidentifier

這則訊息所屬的交談群組識別碼。

conversation_handle

uniqueidentifier

這則訊息所屬的交談之控制代碼。

message_sequence_number

bigint

訊息在交談中的序號。

service_name

nvarchar(512)

交談的目標服務名稱。

service_id

int

交談目標服務的 SQL Server 物件識別碼。

service_contract_name

nvarchar(256)

交談遵照的合約名稱。

service_contract_id

int

交談遵照的合約之 SQL Server 物件識別碼。

message_type_name

nvarchar(256)

描述訊息的訊息類型名稱。

message_type_id

int

描述訊息的訊息類型之 SQL Server 物件識別碼。

validation

nchar(2)

用於訊息的驗證。

E=空白N=無X=XML

message_body

varbinary(MAX)

訊息內容。

權限

若要接收訊息,目前的使用者必須有佇列的 RECEIVE 權限。

範例

A. 接收交談群組中全部訊息的所有資料行

下列範例接收 ExpenseQueue 佇列中下一個可用交談群組的所有可用訊息。陳述式將訊息當作結果集傳回。

RECEIVE * FROM ExpenseQueue ;

B. 接收交談群組中全部訊息的指定資料行

下列範例接收 ExpenseQueue 佇列中下一個可用交談群組的所有可用訊息。陳述式將訊息當作包含 conversation_handlemessage_type_namemessage_body 等資料行的結果集傳回。

RECEIVE conversation_handle, message_type_name, message_body
FROM ExpenseQueue ;

C. 接收佇列中第一個可用的訊息

下列範例從 ExpenseQueue 佇列中接收第一個可用的訊息來作為結果集。

RECEIVE TOP (1) * FROM ExpenseQueue ;

D. 接收指定交談的所有訊息

下列範例從 ExpenseQueue 佇列中接收指定交談的所有可用訊息來作為結果集。

DECLARE @conversation_handle UNIQUEIDENTIFIER ;

SET @conversation_handle = <retrieve conversation from database> ;

RECEIVE *
FROM ExpenseQueue
WHERE conversation_handle = @conversation_handle ;

E. 接收指定交談群組的訊息

下列範例從 ExpenseQueue 佇列中接收指定交談群組的所有可用訊息來作為結果集。

DECLARE @conversation_group_id UNIQUEIDENTIFIER ;

SET @conversation_group_id = 
    <retrieve conversation group ID from database> ;

RECEIVE *
FROM ExpenseQueue
WHERE conversation_group_id = @conversation_group_id ;

F. 接收並放入資料表變數

下列範例從 ExpenseQueue 佇列中接收指定交談群組的所有可用訊息,將它們放入資料表變數中。

DECLARE @conversation_group_id UNIQUEIDENTIFIER ;

DECLARE @procTable TABLE(
     service_instance_id UNIQUEIDENTIFIER,
     handle UNIQUEIDENTIFIER,
     message_sequence_number BIGINT,
     service_name NVARCHAR(512),
     service_contract_name NVARCHAR(256),
     message_type_name NVARCHAR(256),
     validation NCHAR,
     message_body VARBINARY(MAX)) ;

SET @conversation_group_id = <retrieve conversation group ID from database> ;

RECEIVE TOP (1)
    conversation_group_id,
    conversation_handle,
    message_sequence_number,
    service_name,
    service_contract_name,
    message_type_name,
    validation,
    message_body
FROM ExpenseQueue
INTO @procTable
WHERE conversation_group_id = @conversation_group_id ;

G. 接收訊息並無限期等候

下列範例接收 ExpenseQueue 佇列中下一個可用交談群組的所有可用訊息。陳述式會等候到至少有一個可用的訊息,再傳回包含所有訊息資料行的結果集。

WAITFOR (
    RECEIVE *
    FROM ExpenseQueue) ;

H. 接收訊息並等候指定的間隔

下列範例接收 ExpenseQueue 佇列中下一個可用交談群組的所有可用訊息。陳述式會等候 60 秒,或等到至少有一個可用的訊息,兩者中取其先發生者。如果至少有一個可用的訊息,陳述式會傳回包含所有訊息資料行的結果集,否則,就傳回空的結果集。

WAITFOR (
    RECEIVE *
    FROM ExpenseQueue ),
TIMEOUT 60000 ;

I. 接收訊息,修改資料行的類型

下列範例接收 ExpenseQueue 佇列中下一個可用交談群組的所有可用訊息。當訊息類型說明訊息包含 XML 文件時,陳述式會將訊息主體轉換成 XML。

WAITFOR (
    RECEIVE message_type_name,
        CASE
            WHEN validation = 'X' THEN CAST(message_body as XML)
            ELSE NULL
         END AS message_body 
         FROM ExpenseQueue ),
TIMEOUT 60000 ;

J. 接收訊息、從訊息主體擷取資料、擷取交談狀態

下列範例接收 ExpenseQueue 佇列中下一個可用交談群組的下一個可用訊息。當訊息的類型是 //Adventure-Works.com/Expenses/SubmitExpense 時,陳述式會從訊息主體中擷取員工識別碼和項目的清單。陳述式也會從 ConversationState 資料表中擷取交談的狀態。

WAITFOR(
    RECEIVE 
    TOP(1)
      message_type_name,
      COALESCE(
           (SELECT TOP(1) ConversationState
            FROM CurrentConversations AS cc
            WHERE cc.ConversationHandle = conversation_handle),
           'NEW')
      AS ConversationState,
      COALESCE(
          (SELECT TOP(1) ErrorCount
           FROM CurrentConversations AS cc
           WHERE cc.ConversationHandle = conversation_handle), 
           0)
      AS ConversationErrors,
      CASE WHEN message_type_name = N'//Adventure-Works.com/Expenses/SubmitExpense'
          THEN CAST(message_body AS XML).value(
                'declare namespace rpt = "http://Adventure-Works.com/schemas/expenseReport"
                   (/rpt:ExpenseReport/rpt:EmployeeID)[1]', 'nvarchar(20)')
         ELSE NULL
      END AS EmployeeID,
      CASE WHEN message_type_name = N'//Adventure-Works.com/Expenses/SubmitExpense'
          THEN CAST(message_body AS XML).query(
                'declare namespace rpt = "http://Adventure-Works.com/schemas/expenseReport" 
                     /rpt:ExpenseReport/rpt:ItemDetail')
          ELSE NULL
      END AS ItemList
    FROM ExpenseQueue 
), TIMEOUT 60000 ;

請參閱

參考

BEGIN DIALOG CONVERSATION (Transact-SQL)
BEGIN CONVERSATION TIMER (Transact-SQL)
END CONVERSATION (Transact-SQL)
SEND (Transact-SQL)
CREATE QUEUE (Transact-SQL)
ALTER QUEUE (Transact-SQL)
DROP QUEUE (Transact-SQL)

其他資源

Service Broker 教學課程
Conversation Group Locks
交談架構

說明及資訊

取得 SQL Server 2005 協助