Mengembalikan data dari prosedur tersimpan
Berlaku untuk:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics AnalyticsPlatform System (PDW)
Ada tiga cara mengembalikan data dari prosedur ke program panggilan: kumpulan hasil, parameter output, dan kode pengembalian. Artikel ini menyediakan informasi tentang tiga pendekatan.
Mengembalikan data menggunakan tataan hasil
Jika Anda menyertakan pernyataan SELECT dalam isi prosedur tersimpan (tetapi bukan SELECT ... INTO atau INSERT ... SELECT), baris yang ditentukan oleh pernyataan SELECT akan dikirim langsung ke klien. Untuk kumpulan hasil besar, eksekusi prosedur tersimpan tidak akan berlanjut ke pernyataan berikutnya sampai kumpulan hasil telah sepenuhnya dikirim ke klien. Untuk kumpulan hasil kecil, hasilnya ditampung untuk kembali ke klien dan eksekusi akan berlanjut. Jika beberapa pernyataan SELECT tersebut dijalankan selama eksekusi prosedur tersimpan, beberapa set hasil akan dikirim ke klien. Perilaku ini juga berlaku untuk batch Transact-SQL berlapis, prosedur tersimpan berlapis, dan batch Transact-SQL tingkat atas.
Contoh mengembalikan data menggunakan tataan hasil
Contoh berikut menggunakan AdventureWorks2022
database sampel. Contoh ini memperlihatkan prosedur tersimpan LastName
yang mengembalikan nilai dan SalesYTD
untuk semua SalesPerson
baris yang juga muncul dalam vEmployee
tampilan.
USE AdventureWorks2022;
GO
IF OBJECT_ID('Sales.uspGetEmployeeSalesYTD', 'P') IS NOT NULL
DROP PROCEDURE Sales.uspGetEmployeeSalesYTD;
GO
CREATE PROCEDURE Sales.uspGetEmployeeSalesYTD
AS
SET NOCOUNT ON;
SELECT LastName, SalesYTD
FROM Sales.SalesPerson AS sp
JOIN HumanResources.vEmployee AS e ON e.BusinessEntityID = sp.BusinessEntityID;
RETURN;
GO
Mengembalikan data menggunakan parameter output
Jika Anda menentukan kata kunci output untuk parameter dalam definisi prosedur, prosedur dapat mengembalikan nilai parameter saat ini ke program panggilan saat prosedur keluar. Untuk menyimpan nilai parameter dalam variabel yang dapat digunakan dalam program panggilan, program panggilan harus menggunakan kata kunci output saat menjalankan prosedur. Untuk informasi selengkapnya tentang jenis data apa yang dapat digunakan sebagai parameter output, lihat CREATE PROCEDURE (Transact-SQL).
Contoh parameter output
Contoh berikut menunjukkan prosedur dengan parameter input dan output. Parameter @SalesPerson
akan menerima nilai input yang ditentukan oleh program panggilan. Pernyataan SELECT menggunakan nilai yang diteruskan ke parameter input untuk mendapatkan nilai yang benar SalesYTD
. Pernyataan SELECT juga menetapkan nilai ke @SalesYTD
parameter output, yang mengembalikan nilai ke program panggilan saat prosedur keluar.
USE AdventureWorks2022;
GO
IF OBJECT_ID('Sales.uspGetEmployeeSalesYTD', 'P') IS NOT NULL
DROP PROCEDURE Sales.uspGetEmployeeSalesYTD;
GO
CREATE PROCEDURE Sales.uspGetEmployeeSalesYTD
@SalesPerson nvarchar(50),
@SalesYTD money OUTPUT
AS
SET NOCOUNT ON;
SELECT @SalesYTD = SalesYTD
FROM Sales.SalesPerson AS sp
JOIN HumanResources.vEmployee AS e ON e.BusinessEntityID = sp.BusinessEntityID
WHERE LastName = @SalesPerson;
RETURN;
GO
Contoh berikut memanggil prosedur yang dibuat dalam contoh pertama dan menyimpan parameter @SalesYTD
output yang dikembalikan dari prosedur yang disebut ke dalam @SalesYTDBySalesPerson
variabel.
Contohnya:
- Menyatakan variabel
@SalesYTDBySalesPerson
untuk menerima nilai output prosedur. - Menjalankan prosedur yang
Sales.uspGetEmployeeSalesYTD
menentukan nama belakang untuk parameter input. Simpan nilai output dalam variabel@SalesYTDBySalesPerson
. - Memanggil PRINT untuk menampilkan nilai yang disimpan ke
@SalesYTDBySalesPerson
.
DECLARE @SalesYTDBySalesPerson money;
EXECUTE Sales.uspGetEmployeeSalesYTD
N'Blythe', @SalesYTD = @SalesYTDBySalesPerson OUTPUT;
PRINT 'Year-to-date sales for this employee is ' +
CONVERT(varchar(10),@SalesYTDBySalesPerson);
GO
Nilai input juga dapat ditentukan untuk parameter output saat prosedur dijalankan. Ini memungkinkan prosedur untuk menerima nilai dari program panggilan, mengubah atau melakukan operasi dengan nilai , lalu mengembalikan nilai baru ke program panggilan. Dalam contoh sebelumnya, @SalesYTDBySalesPerson
variabel dapat diberi nilai sebelum program memanggil Sales.uspGetEmployeeSalesYTD
prosedur. Pernyataan eksekusi akan meneruskan @SalesYTDBySalesPerson
nilai variabel ke @SalesYTD
dalam parameter output. Kemudian dalam isi prosedur, nilai dapat digunakan untuk perhitungan yang menghasilkan nilai baru. Nilai baru akan diteruskan kembali dari prosedur melalui parameter output, memperbarui nilai dalam @SalesYTDBySalesPerson
variabel ketika prosedur keluar. Ini sering disebut sebagai "kemampuan referensi pass-by-."
Jika Anda menentukan output untuk parameter saat memanggil prosedur dan parameter tersebut tidak ditentukan dengan menggunakan output dalam definisi prosedur, Anda mendapatkan pesan kesalahan. Namun, Anda dapat menjalankan prosedur dengan parameter output dan tidak menentukan output saat menjalankan prosedur. Tidak ada kesalahan yang dikembalikan, tetapi Anda tidak dapat menggunakan nilai output dalam program panggilan.
Menggunakan jenis data kursor dalam parameter output
Prosedur T-SQL dapat menggunakan jenis data kursor hanya untuk parameter output. Jika jenis data kursor ditentukan untuk parameter, kata kunci yang bervariasi dan output harus ditentukan untuk parameter tersebut dalam definisi prosedur. Parameter dapat ditentukan sebagai hanya output, tetapi jika berbagai kata kunci ditentukan dalam deklarasi parameter, jenis data harus kursor dan kata kunci output juga harus ditentukan.
Catatan
Jenis data kursor tidak dapat terikat ke variabel aplikasi melalui API database seperti OLE DB, ODBC, ADO, dan DB-Library. Karena parameter output harus terikat sebelum aplikasi dapat menjalankan prosedur, prosedur dengan parameter output kursor tidak dapat dipanggil dari API database. Prosedur ini dapat dipanggil dari batch Transact-SQL, prosedur, atau pemicu hanya ketika variabel output kursor ditetapkan ke variabel kursor lokal Transact-SQL.
Aturan untuk parameter output kursor
Aturan berikut berkaitan dengan parameter output kursor saat prosedur dijalankan:
Untuk kursor hanya maju, baris yang dikembalikan dalam tataan hasil kursor hanyalah baris di dan di luar posisi kursor pada akhir eksekusi prosedur, misalnya:
Kursor yang tidak dapat digulir dibuka dalam prosedur pada kumpulan hasil bernama
RS
100 baris.Prosedur ini mengambil lima baris pertama dari tataan
RS
hasil .Prosedur kembali ke pemanggilnya.
Tataan
RS
hasil yang dikembalikan ke pemanggil terdiri dari baris dari 6 hingga 100 ,RS
dan kursor di pemanggil diposisikan sebelum barisRS
pertama .
Untuk kursor hanya-terusan, jika kursor diposisikan sebelum baris pertama saat prosedur keluar, seluruh tataan hasil dikembalikan ke batch panggilan, prosedur, atau pemicu. Saat dikembalikan, posisi kursor diatur sebelum baris pertama.
Untuk kursor hanya-terusan, jika kursor diposisikan di luar akhir baris terakhir saat prosedur keluar, tataan hasil kosong dikembalikan ke batch, prosedur, atau pemicu panggilan.
Catatan
Tataan hasil kosong tidak sama dengan nilai null.
Untuk kursor yang dapat digulir, semua baris dalam tataan hasil dikembalikan ke batch panggilan, prosedur, atau pemicu saat prosedur keluar. Ketika dikembalikan, posisi kursor dibiarkan pada posisi pengambilan terakhir yang dijalankan dalam prosedur.
Untuk semua jenis kursor, jika kursor ditutup, maka nilai null diteruskan kembali ke batch, prosedur, atau pemicu panggilan. Ini juga akan terjadi jika kursor ditetapkan ke parameter, tetapi kursor tersebut tidak pernah dibuka.
Catatan
Status tertutup hanya penting pada waktu pengembalian. Misalnya, valid untuk menutup bagian kursor dari cara melalui prosedur, untuk membukanya lagi nanti dalam prosedur, dan mengembalikan hasil kursor yang diatur ke batch panggilan, prosedur, atau pemicu.
Contoh parameter output kursor
Dalam contoh berikut, prosedur dibuat yang menentukan parameter output, @CurrencyCursor
menggunakan jenis data kursor. Prosedur kemudian dipanggil dalam batch.
Pertama, buat prosedur yang menyatakan lalu buka kursor pada Currency
tabel.
USE AdventureWorks2022;
GO
IF OBJECT_ID ( 'dbo.uspCurrencyCursor', 'P' ) IS NOT NULL
DROP PROCEDURE dbo.uspCurrencyCursor;
GO
CREATE PROCEDURE dbo.uspCurrencyCursor
@CurrencyCursor CURSOR VARYING OUTPUT
AS
SET NOCOUNT ON;
SET @CurrencyCursor = CURSOR FORWARD_ONLY STATIC FOR
SELECT CurrencyCode, Name
FROM Sales.Currency;
OPEN @CurrencyCursor;
GO
Selanjutnya, jalankan batch yang mendeklarasikan variabel kursor lokal, jalankan prosedur untuk menetapkan kursor ke variabel lokal, lalu mengambil baris dari kursor.
USE AdventureWorks2022;
GO
DECLARE @MyCursor CURSOR;
EXEC dbo.uspCurrencyCursor @CurrencyCursor = @MyCursor OUTPUT;
WHILE (@@FETCH_STATUS = 0)
BEGIN;
FETCH NEXT FROM @MyCursor;
END;
CLOSE @MyCursor;
DEALLOCATE @MyCursor;
GO
Mengembalikan data menggunakan kode pengembalian
Prosedur dapat mengembalikan nilai bilangan bulat yang disebut kode pengembalian untuk menunjukkan status eksekusi prosedur. Anda menentukan kode pengembalian untuk prosedur menggunakan pernyataan RETURN. Seperti parameter output, Anda harus menyimpan kode pengembalian dalam variabel ketika prosedur dijalankan untuk menggunakan nilai kode pengembalian dalam program panggilan. Misalnya, variabel @result
penugasan jenis int
data digunakan untuk menyimpan kode pengembalian dari prosedur my_proc
, seperti:
DECLARE @result int;
EXECUTE @result = my_proc;
GO
Kode pengembalian umumnya digunakan dalam blok kontrol aliran dalam prosedur untuk mengatur nilai kode pengembalian untuk setiap kemungkinan situasi kesalahan. Anda dapat menggunakan @@ERROR
fungsi setelah pernyataan Transact-SQL untuk mendeteksi apakah terjadi kesalahan selama eksekusi pernyataan. Sebelum pengenalan TRY
//CATCH
THROW
penanganan kesalahan dalam kode pengembalian Transact-SQL terkadang diperlukan untuk menentukan keberhasilan atau kegagalan prosedur tersimpan. Prosedur tersimpan harus selalu menunjukkan kegagalan dengan kesalahan (dihasilkan dengan THROW
/RAISERROR
jika perlu), dan tidak mengandalkan kode pengembalian untuk menunjukkan kegagalan. Anda juga harus menghindari penggunaan kode pengembalian untuk mengembalikan data aplikasi.
Contoh kode pengembalian
Contoh berikut menunjukkan usp_GetSalesYTD
prosedur dengan penanganan kesalahan yang menetapkan nilai kode pengembalian khusus untuk berbagai kesalahan. Tabel berikut ini memperlihatkan nilai bilangan bulat yang ditetapkan oleh prosedur untuk setiap kemungkinan kesalahan, dan arti yang sesuai untuk setiap nilai.
Mengembalikan nilai kode | Makna |
---|---|
0 | Eksekusi berhasil. |
1 | Nilai parameter yang diperlukan tidak ditentukan. |
2 | Nilai parameter yang ditentukan tidak valid. |
3 | Terjadi kesalahan saat mendapatkan nilai penjualan. |
4 | Nilai penjualan NULL ditemukan untuk tenaga penjual. |
Contoh membuat prosedur bernama Sales.usp_GetSalesYTD
, yang:
- Mendeklarasikan
@SalesPerson
parameter dan mengatur nilai defaultnya keNULL
. Parameter ini dimaksudkan untuk mengambil nama belakang orang penjualan. - Memvalidasi
@SalesPerson
parameter.- Jika
@SalesPerson
NULL, prosedur mencetak pesan dan mengembalikan kode1
pengembalian . - Jika tidak, jika
@SalesPerson
parameter bukan NULL, prosedur memeriksa jumlah baris dalamHumanResources.vEmployee
tabel dengan nama belakang yang sama dengan nilai@SalesPerson
. Jika jumlahnya nol, prosedur mengembalikan kode2
pengembalian .
- Jika
- Mengkueri penjualan tahun ke tanggal untuk sales person dengan nama belakang yang ditentukan dan menetapkannya ke
@SalesYTD
parameter output. - Memeriksa kesalahan SQL Server dengan menguji @@ERROR (Transact-SQL).
- Jika
@@ERROR
tidak sama dengan nol, prosedur mengembalikan kode3
pengembalian . - Jika
@@ERROR
sama dengan nol, prosedur memeriksa untuk melihat apakah@SalesYTD
nilai parameter adalah NULL. Jika tidak ada penjualan tahun ke tanggal yang ditemukan, prosedur mengembalikan kode4
pengembalian . - Jika tidak ada kondisi sebelumnya yang benar, prosedur mengembalikan kode
0
pengembalian .
- Jika
- Jika tercapai, pernyataan akhir dalam prosedur tersimpan memanggil prosedur tersimpan secara rekursif tanpa menentukan nilai input.
Di akhir contoh, kode disediakan untuk menjalankan Sales.usp_GetSalesYTD
prosedur sambil menentukan nama belakang untuk parameter input dan menyimpan nilai output dalam variabel @SalesYTD
.
USE AdventureWorks2022;
GO
CREATE PROCEDURE Sales.usp_GetSalesYTD
@SalesPerson NVARCHAR(50) = NULL,
@SalesYTD MONEY=NULL OUTPUT
AS
IF @SalesPerson IS NULL
BEGIN
PRINT 'ERROR: You must specify a last name for the sales person.'
RETURN (1)
END
ELSE
BEGIN
IF(SELECT COUNT(*)FROM HumanResources.vEmployee WHERE LastName=@SalesPerson)=0
RETURN (2)
END
SELECT @SalesYTD=SalesYTD
FROM Sales.SalesPerson AS sp
JOIN HumanResources.vEmployee AS e ON e.BusinessEntityID=sp.BusinessEntityID
WHERE LastName=@SalesPerson;
IF @@ERROR<>0
BEGIN
RETURN (3)
END
ELSE
BEGIN
IF @SalesYTD IS NULL
RETURN (4)
ELSE
RETURN (0)
END
EXEC Sales.usp_GetSalesYTD;
GO
DECLARE @SalesYTDForSalesPerson money, @ret_code int;
EXECUTE Sales.usp_GetSalesYTD N'Blythe', @SalesYTD = @SalesYTDForSalesPerson OUTPUT;
PRINT N'Year-to-date sales for this employee is ' +
CONVERT(varchar(10), @SalesYTDForSalesPerson);
GO
Contoh berikut membuat program untuk menangani kode pengembalian yang dikembalikan dari usp_GetSalesYTD
prosedur.
Contohnya:
- Mendeklarasikan variabel
@SalesYTDForSalesPerson
dan@ret_code
untuk menerima nilai output dan mengembalikan kode prosedur. Sales.usp_GetSalesYTD
Menjalankan prosedur dengan nilai input yang ditentukan untuk@SalesPerson
dan menyimpan nilai output dan mengembalikan kode dalam variabel.- Memeriksa kode pengembalian di
@ret_code
dan memanggil PRINT (Transact-SQL) untuk menampilkan pesan yang sesuai.
DECLARE @SalesYTDForSalesPerson money, @ret_code int;
EXECUTE @ret_code = Sales.usp_GetSalesYTD
N'Blythe', @SalesYTD = @SalesYTDForSalesPerson OUTPUT;
IF @ret_code = 0
BEGIN
PRINT 'Procedure executed successfully';
PRINT 'Year-to-date sales for this employee is ' + CONVERT(varchar(10),@SalesYTDForSalesPerson);
END
ELSE IF @ret_code = 1
PRINT 'ERROR: You must specify a last name for the sales person.';
ELSE IF @ret_code = 2
PRINT 'ERROR: You must enter a valid last name for the sales person.';
ELSE IF @ret_code = 3
PRINT 'ERROR: An error occurred getting sales value.';
ELSE IF @ret_code = 4
PRINT 'ERROR: No sales recorded for this employee.';
GO
Konten terkait
Untuk informasi selengkapnya tentang prosedur tersimpan dan konsep terkait, lihat artikel berikut ini:
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk