Jadi katakanlah Anda memiliki prosedur tersimpan di tempdb:
USE tempdb;
GO
CREATE PROCEDURE dbo.my_procedure
AS
BEGIN
SET NOCOUNT ON;
SELECT foo = 1, bar = 'tooth';
END
GO
Ada cara yang cukup berbelit-belit untuk menentukan metadata yang akan dihasilkan oleh prosedur tersimpan. Ada beberapa peringatan, termasuk prosedur yang hanya dapat menampilkan satu set hasil, dan tebakan terbaik akan dibuat tentang tipe data jika tidak dapat ditentukan dengan tepat. Ini membutuhkan penggunaan OPENQUERY
dan server tertaut loopback dengan 'DATA ACCESS'
properti disetel ke true. Anda dapat memeriksa sys.servers untuk melihat apakah Anda sudah memiliki server yang valid, tetapi mari kita buat secara manual bernama loopback
:
EXEC master..sp_addlinkedserver
@server = 'loopback',
@srvproduct = '',
@provider = 'SQLNCLI',
@datasrc = @@SERVERNAME;
EXEC master..sp_serveroption
@server = 'loopback',
@optname = 'DATA ACCESS',
@optvalue = 'TRUE';
Sekarang Anda dapat melakukan kueri ini sebagai server tertaut, Anda dapat menggunakan hasil kueri apa pun (termasuk panggilan prosedur tersimpan) sebagai SELECT
biasa . Jadi Anda dapat melakukan ini (perhatikan bahwa awalan basis data adalah penting, jika tidak, Anda akan mendapatkan kesalahan 11529 dan 2812):
SELECT * FROM OPENQUERY(loopback, 'EXEC tempdb.dbo.my_procedure;');
Jika kita dapat melakukan SELECT *
, kita juga dapat melakukan SELECT * INTO
:
SELECT * INTO #tmp FROM OPENQUERY(loopback, 'EXEC tempdb.dbo.my_procedure;');
Dan setelah tabel #tmp itu ada, kita dapat menentukan metadata dengan mengatakan (dengan asumsi SQL Server 2005 atau lebih tinggi):
SELECT c.name, [type] = t.name, c.max_length, c.[precision], c.scale
FROM sys.columns AS c
INNER JOIN sys.types AS t
ON c.system_type_id = t.system_type_id
AND c.user_type_id = t.user_type_id
WHERE c.[object_id] = OBJECT_ID('tempdb..#tmp');
(Jika Anda menggunakan SQL Server 2000, Anda dapat melakukan sesuatu yang serupa dengan syscolumns, tetapi saya tidak memiliki instance 2000 yang berguna untuk memvalidasi kueri yang setara.)
Hasil:
name type max_length precision scale
--------- ------- ---------- --------- -----
foo int 4 10 0
bar varchar 5 0 0
Di Denali, ini akan jauh lebih mudah. Sekali lagi masih ada batasan set hasil pertama tetapi Anda tidak perlu menyiapkan server tertaut dan melompati semua rintangan itu. Anda cukup mengatakan:
DECLARE @sql NVARCHAR(MAX) = N'EXEC tempdb.dbo.my_procedure;';
SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set(@sql, NULL, 1);
Hasil:
name system_type_name
--------- ----------------
foo int
bar varchar(5)
Sampai Denali, saya sarankan akan lebih mudah untuk menyingsingkan lengan baju Anda dan mencari tahu tipe data Anda sendiri. Bukan hanya karena membosankan untuk melalui langkah-langkah di atas, tetapi juga karena Anda jauh lebih mungkin untuk membuat tebakan yang benar (atau setidaknya lebih akurat) daripada mesin, karena tipe data menebak yang dibuat mesin akan didasarkan pada runtime output, tanpa pengetahuan eksternal tentang domain nilai yang mungkin. Faktor ini akan tetap berlaku di Denali juga, jadi jangan terkesan bahwa fitur penemuan metadata baru adalah segalanya, mereka hanya membuat hal di atas sedikit kurang membosankan.
Oh dan untuk beberapa gotcha potensial lainnya dengan OPENQUERY
, lihat artikel Erland Sommarskog di sini:
http://www.sommarskog.se/share_data.html#OPENQUERY