Bagikan melalui


RECEIVE (Transact-SQL)

Berlaku untuk: SQL Server Azure SQL Managed Instance

Mengambil satu atau beberapa pesan dari antrean. Bergantung pada pengaturan retensi untuk antrean, menghapus pesan dari antrean atau memperbarui status pesan dalam antrean.

Konvensi sintaks transact-SQL

Sintaksis

[ 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 ]  
}     [ ,...n ]   
  
<queue> ::=  
{ database_name.schema_name.queue_name | schema_name.queue_name | queue_name }

Catatan

Untuk melihat sintaks Transact-SQL untuk SQL Server 2014 (12.x) dan versi yang lebih lama, lihat Dokumentasi versi sebelumnya.

Argumen

WAITFOR

Menentukan bahwa pernyataan RECEIVE menunggu pesan tiba di antrean, jika saat ini tidak ada pesan.

TOP( n )

Menentukan jumlah maksimum pesan yang akan dikembalikan. Jika klausul ini tidak ditentukan, semua pesan dikembalikan yang memenuhi kriteria pernyataan.

column_specifier

*
Menentukan bahwa kumpulan hasil berisi semua kolom dalam antrean.

column_name
Nama kolom yang akan disertakan dalam tataan hasil.

expression
Nama kolom, konstanta, fungsi, atau kombinasi nama kolom, konstanta, dan fungsi apa pun yang disambungkan oleh operator.

column_alias
Nama alternatif untuk mengganti nama kolom dalam tataan hasil.

DARI

Menentukan antrean yang berisi pesan yang akan diambil.

database_name
Nama database yang berisi antrean untuk menerima pesan. Ketika tidak ada nama database yang disediakan, default ke database saat ini.

schema_name
Nama skema yang memiliki antrean untuk menerima pesan. Ketika tidak ada nama skema yang disediakan, default ke skema default untuk pengguna saat ini.

queue_name
Nama antrean untuk menerima pesan.

INTO table_variable

Menentukan variabel tabel tempat RECEIVE menempatkan pesan. Variabel tabel harus memiliki jumlah kolom yang sama seperti dalam pesan. Jenis data setiap kolom dalam variabel tabel harus dikonversi secara implisit ke jenis data kolom yang sesuai dalam pesan. Jika INTO tidak ditentukan, pesan dikembalikan sebagai tataan hasil.

WHERE

Menentukan percakapan atau grup percakapan untuk pesan yang diterima. Jika dihilangkan, mengembalikan pesan dari grup percakapan berikutnya yang tersedia.

conversation_handle = conversation_handle
Menentukan percakapan untuk pesan yang diterima. Handel percakapan yang disediakan harus berupa pengidentifikasi unik, atau jenis yang dapat dikonversi ke pengidentifikasi unik.

conversation_group_id = conversation_group_id
Menentukan grup percakapan untuk pesan yang diterima. ID grup percakapan yang disediakan harus menjadi pengidentifikasi unik, atau jenis yang dapat dikonversi ke pengidentifikasi unik.

Batas waktu habis

Menentukan jumlah waktu, dalam milidetik, agar pernyataan menunggu pesan. Klausa ini hanya dapat digunakan dengan klausa WAITFOR. Jika klausa ini tidak ditentukan, atau waktu habis adalah -1, waktu tunggu tidak terbatas. Jika batas waktu habis, RECEIVE mengembalikan tataan hasil kosong.

Keterangan

Penting

Jika pernyataan RECEIVE bukan pernyataan pertama dalam batch atau prosedur tersimpan, pernyataan sebelumnya harus diakhapi dengan titik koma (;).

Pernyataan RECEIVE membaca pesan dari antrean dan mengembalikan tataan hasil. Kumpulan hasil terdiri dari nol atau lebih baris, yang masing-masing berisi satu pesan. Jika klausa INTO tidak digunakan, dan column_specifier tidak menetapkan nilai ke variabel lokal, pernyataan mengembalikan hasil yang diatur ke program panggilan.

Pesan yang dikembalikan oleh pernyataan RECEIVE bisa dari jenis pesan yang berbeda. Aplikasi dapat menggunakan kolom untuk merutekan message_type_name setiap pesan ke kode yang menangani jenis pesan terkait. Ada dua kelas jenis pesan:

  • Jenis pesan yang ditentukan aplikasi yang dibuat dengan menggunakan pernyataan CREATE MESSAGE TYPE. Kumpulan jenis pesan yang ditentukan aplikasi yang diizinkan dalam percakapan ditentukan oleh kontrak Service Broker yang ditentukan untuk percakapan.

  • Pesan sistem Service Broker yang mengembalikan status atau informasi kesalahan.

Pernyataan RECEIVE menghapus pesan yang diterima dari antrean kecuali antrean menentukan retensi pesan. Saat pengaturan RETENSI untuk antrean AKTIF, pernyataan RECEIVE memperbarui status kolom ke 0 dan meninggalkan pesan dalam antrean. Ketika transaksi yang berisi pernyataan RECEIVE digulung balik, semua perubahan pada antrean dalam transaksi juga digulung balik, mengembalikan pesan ke antrean.

Semua pesan yang dikembalikan oleh pernyataan RECEIVE termasuk dalam grup percakapan yang sama. Pernyataan RECEIVE mengunci grup percakapan untuk pesan yang dikembalikan hingga transaksi yang berisi pernyataan selesai. Pernyataan RECEIVE mengembalikan pesan yang memiliki status .1 Tataan hasil yang dikembalikan oleh pernyataan RECEIVE secara implisit diurutkan:

  • Jika pesan dari beberapa percakapan memenuhi kondisi klausa WHERE, pernyataan RECEIVE mengembalikan semua pesan dari satu percakapan sebelum menampilkan pesan untuk percakapan lain. Percakapan diproses dalam urutan tingkat prioritas turun.

  • Untuk percakapan tertentu, pernyataan RECEIVE mengembalikan pesan dalam urutan naik message_sequence_number .

Klausa WHERE dari pernyataan RECEIVE hanya dapat berisi satu kondisi pencarian yang menggunakan atau conversation_handle conversation_group_id. Kondisi pencarian tidak boleh berisi satu atau beberapa kolom lain dalam antrean. conversation_handle atau conversation_group_id tidak dapat menjadi ekspresi. Kumpulan pesan yang dikembalikan tergantung pada kondisi yang ditentukan dalam klausa WHERE:

  • Jika conversation_handle ditentukan, RECEIVE mengembalikan semua pesan dari percakapan yang ditentukan yang tersedia dalam antrean.

  • Jika conversation_group_id ditentukan, RECEIVE mengembalikan semua pesan yang tersedia dalam antrean dari percakapan apa pun yang merupakan anggota grup percakapan yang ditentukan.

  • Jika tidak ada klausa WHERE, RECEIVE menentukan grup percakapan mana:

    • Memiliki satu atau beberapa pesan dalam antrean.

    • Belum dikunci oleh pernyataan RECEIVE lain.

    • Memiliki tingkat prioritas tertinggi dari semua grup percakapan yang memenuhi kriteria ini.

    RECEIVE kemudian mengembalikan semua pesan yang tersedia dalam antrean dari percakapan apa pun yang merupakan anggota grup percakapan yang dipilih.

Jika handel percakapan atau pengidentifikasi grup percakapan yang ditentukan dalam klausa WHERE tidak ada, atau tidak terkait dengan antrean yang ditentukan, pernyataan RECEIVE mengembalikan kesalahan.

Jika antrean yang ditentukan dalam pernyataan RECEIVE memiliki status antrean yang diatur ke NONAKTIF, pernyataan gagal dengan kesalahan Transact-SQL.

Ketika klausul WAITFOR ditentukan, pernyataan menunggu waktu habis yang ditentukan, atau hingga kumpulan hasil tersedia. Jika antrean dihilangkan atau status antrean diatur ke NONAKTIF saat pernyataan sedang menunggu, pernyataan segera mengembalikan kesalahan. Jika pernyataan RECEIVE menentukan grup percakapan atau handel percakapan dan layanan untuk percakapan tersebut dihilangkan atau dipindahkan ke antrean lain, pernyataan RECEIVE melaporkan kesalahan Transact-SQL.

RECEIVE tidak valid dalam fungsi yang ditentukan pengguna.

Pernyataan RECEIVE tidak memiliki pencegahan kelaparan prioritas. Jika satu pernyataan RECEIVE mengunci grup percakapan dan mengambil banyak pesan dari percakapan berprioritas rendah, tidak ada pesan yang dapat diterima dari percakapan prioritas tinggi dalam grup. Untuk mencegah hal ini, saat Anda mengambil pesan dari percakapan berprioritas rendah, gunakan klausa TOP untuk membatasi jumlah pesan yang diambil oleh setiap pernyataan RECEIVE.

Kolom Antrean

Tabel berikut mencantumkan kolom dalam antrean:

Nama kolom Jenis data Deskripsi
status kecil Status pesan. Untuk pesan yang dikembalikan oleh perintah RECEIVE, statusnya selalu 0. Pesan dalam antrean dapat berisi salah satu nilai berikut:

0=Siap
1=Pesan diterima
2=Belum selesai
3=Pesan terkirim yang dipertahankan
priority kecil Tingkat prioritas percakapan yang diterapkan ke pesan.
queuing_order bigint Nomor pesanan dalam antrean.
conversation_group_id pengidentifikasi unik Pengidentifikasi untuk grup percakapan tempat pesan ini berada.
conversation_handle pengidentifikasi unik Tangani untuk percakapan yang menjadi bagian pesan ini.
message_sequence_number bigint Nomor urutan pesan dalam percakapan.
service_name nvarchar(128) Nama layanan tempat percakapan berada.
service_id int Pengidentifikasi objek SQL Server dari layanan tempat percakapan berada.
service_contract_name nvarchar(128) Nama kontrak yang diikuti percakapan.
service_contract_id int Pengidentifikasi objek SQL Server dari kontrak yang diikuti percakapan.
message_type_name nvarchar(128) Nama jenis pesan yang menjelaskan format pesan. Pesan dapat berupa jenis pesan aplikasi atau pesan sistem Broker.
message_type_id int Pengidentifikasi objek SQL Server dari jenis pesan yang menjelaskan pesan.
validation nchar(2) Validasi yang digunakan untuk pesan.

E=Kosong
N=Tidak ada
X=XML
message_body varbinary(MAX) Konten pesan.

Izin

Untuk menerima pesan, pengguna saat ini harus memiliki izin RECEIVE pada antrean.

Contoh

J. Menerima semua kolom untuk semua pesan dalam grup percakapan

Contoh berikut menerima semua pesan yang tersedia untuk grup percakapan berikutnya yang ExpenseQueue tersedia dari antrean. Pernyataan mengembalikan pesan sebagai kumpulan hasil.

RECEIVE * FROM ExpenseQueue ;  

B. Menerima kolom yang ditentukan untuk semua pesan dalam grup percakapan

Contoh berikut menerima semua pesan yang tersedia untuk grup percakapan berikutnya yang ExpenseQueue tersedia dari antrean. Pernyataan mengembalikan pesan sebagai kumpulan hasil yang berisi kolom conversation_handle, , message_type_namedan message_body.

RECEIVE conversation_handle, message_type_name, message_body  
FROM ExpenseQueue ;  

C. Menerima pesan pertama yang tersedia dalam antrean

Contoh berikut menerima pesan pertama yang ExpenseQueue tersedia dari antrean sebagai kumpulan hasil.

RECEIVE TOP (1) * FROM ExpenseQueue ;  

D. Menerima semua pesan untuk percakapan tertentu

Contoh berikut menerima semua pesan yang tersedia untuk percakapan yang ditentukan dari ExpenseQueue antrean sebagai kumpulan hasil.

DECLARE @conversation_handle UNIQUEIDENTIFIER ;  
  
SET @conversation_handle = <retrieve conversation from database> ;  
  
RECEIVE *  
FROM ExpenseQueue  
WHERE conversation_handle = @conversation_handle ;  

E. Menerima pesan untuk grup percakapan tertentu

Contoh berikut menerima semua pesan yang tersedia untuk grup percakapan yang ditentukan dari ExpenseQueue antrean sebagai kumpulan hasil.

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. Menerima ke dalam variabel tabel

Contoh berikut menerima semua pesan yang tersedia untuk grup percakapan tertentu dari ExpenseQueue antrean ke dalam variabel tabel.

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. Menerima pesan dan menunggu tanpa batas waktu

Contoh berikut menerima semua pesan yang tersedia untuk grup percakapan berikutnya yang tersedia dalam ExpenseQueue antrean. Pernyataan menunggu hingga setidaknya satu pesan tersedia lalu mengembalikan tataan hasil yang berisi semua kolom pesan.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue) ;  

H. Menerima pesan dan menunggu interval tertentu

Contoh berikut menerima semua pesan yang tersedia untuk grup percakapan berikutnya yang tersedia dalam ExpenseQueue antrean. Pernyataan menunggu selama 60 detik atau hingga setidaknya satu pesan tersedia, mana pun yang terjadi terlebih dahulu. Pernyataan mengembalikan tataan hasil yang berisi semua kolom pesan jika setidaknya satu pesan tersedia. Jika tidak, pernyataan mengembalikan tataan hasil kosong.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue ),  
TIMEOUT 60000 ;  

I. Menerima pesan, memodifikasi jenis kolom

Contoh berikut menerima semua pesan yang tersedia untuk grup percakapan berikutnya yang tersedia dalam ExpenseQueue antrean. Saat jenis pesan menyatakan bahwa pesan berisi dokumen XML, pernyataan mengonversi isi pesan ke 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. Menerima pesan, mengekstrak data dari isi pesan, mengambil status percakapan

Contoh berikut menerima pesan berikutnya yang tersedia untuk grup percakapan berikutnya yang tersedia dalam ExpenseQueue antrean. Ketika pesan berjenis //Adventure-Works.com/Expenses/SubmitExpense, pernyataan mengekstrak ID karyawan dan daftar item dari isi pesan. Pernyataan ini juga mengambil status untuk percakapan dari ConversationState tabel.

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 = "https://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 = "https://Adventure-Works.com/schemas/expenseReport"   
                     /rpt:ExpenseReport/rpt:ItemDetail')  
          ELSE NULL  
      END AS ItemList  
    FROM ExpenseQueue   
), TIMEOUT 60000 ;