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.
Sintaks
[ 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 }
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 =Siap1 =Pesan diterima2 =Belum selesai3 =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 =KosongN =Tidak adaX =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_name
dan 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 ;