तो मान लें कि आपके पास tempdb में एक संग्रहीत कार्यविधि है:
USE tempdb;
GO
CREATE PROCEDURE dbo.my_procedure
AS
BEGIN
SET NOCOUNT ON;
SELECT foo = 1, bar = 'tooth';
END
GO
एक बहुत ही जटिल तरीका है जिससे आप मेटाडेटा को निर्धारित करने के बारे में जा सकते हैं कि संग्रहीत प्रक्रिया आउटपुट होगी। प्रक्रिया सहित कई चेतावनी हैं, केवल एक परिणाम सेट को आउटपुट कर सकते हैं, और यह कि डेटा प्रकार के बारे में सबसे अच्छा अनुमान लगाया जाएगा यदि इसे ठीक से निर्धारित नहीं किया जा सकता है। इसके लिए OPENQUERY
. के उपयोग की आवश्यकता है और 'DATA ACCESS'
. के साथ एक लूपबैक लिंक्ड सर्वर संपत्ति सत्य पर सेट है। आप यह देखने के लिए sys.servers की जांच कर सकते हैं कि क्या आपके पास पहले से एक वैध सर्वर है, लेकिन चलिए केवल एक मैन्युअल रूप से बनाते हैं जिसे loopback
कहा जाता है :
EXEC master..sp_addlinkedserver
@server = 'loopback',
@srvproduct = '',
@provider = 'SQLNCLI',
@datasrc = @@SERVERNAME;
EXEC master..sp_serveroption
@server = 'loopback',
@optname = 'DATA ACCESS',
@optvalue = 'TRUE';
अब जब आप इसे एक लिंक किए गए सर्वर के रूप में क्वेरी कर सकते हैं, तो आप किसी भी क्वेरी के परिणाम (एक संग्रहीत प्रक्रिया कॉल सहित) को नियमित SELECT
के रूप में उपयोग कर सकते हैं . तो आप यह कर सकते हैं (ध्यान दें कि डेटाबेस उपसर्ग है महत्वपूर्ण, अन्यथा आपको 11529 और 2812 त्रुटि मिलेगी):
SELECT * FROM OPENQUERY(loopback, 'EXEC tempdb.dbo.my_procedure;');
अगर हम एक SELECT *
perform कर सकते हैं , हम एक SELECT * INTO
. भी कर सकते हैं :
SELECT * INTO #tmp FROM OPENQUERY(loopback, 'EXEC tempdb.dbo.my_procedure;');
और एक बार जब #tmp तालिका मौजूद हो जाती है, तो हम मेटाडेटा को यह कहकर निर्धारित कर सकते हैं (SQL Server 2005 या इससे अधिक मानकर):
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');
(यदि आप SQL Server 2000 का उपयोग कर रहे हैं, तो आप syscolumns के साथ भी कुछ ऐसा ही कर सकते हैं, लेकिन मेरे पास समतुल्य क्वेरी को सत्यापित करने के लिए 2000 इंस्टेंस आसान नहीं है।)
परिणाम:
name type max_length precision scale
--------- ------- ---------- --------- -----
foo int 4 10 0
bar varchar 5 0 0
Denali में, यह बहुत, बहुत, बहुत आसान होगा। फिर से पहले परिणाम सेट की एक सीमा है, लेकिन आपको एक लिंक किए गए सर्वर को सेट करने और उन सभी हुप्स के माध्यम से कूदने की आवश्यकता नहीं है। आप बस इतना ही कह सकते हैं:
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);
परिणाम:
name system_type_name
--------- ----------------
foo int
bar varchar(5)
डेनाली तक, मेरा सुझाव है कि केवल अपनी आस्तीन ऊपर करना और डेटा प्रकारों को स्वयं समझना आसान होगा। सिर्फ इसलिए नहीं कि उपरोक्त चरणों से गुजरना कठिन है, बल्कि इसलिए भी कि आप इंजन की तुलना में सही (या कम से कम अधिक सटीक) अनुमान लगाने की अधिक संभावना रखते हैं, क्योंकि डेटा प्रकार अनुमान लगाता है कि इंजन रनटाइम पर आधारित होगा आउटपुट, संभावित मूल्यों के क्षेत्र के किसी बाहरी ज्ञान के बिना। यह कारक डेनाली में भी सही रहेगा, इसलिए यह आभास न दें कि नई मेटाडेटा खोज सुविधाएँ पूरी तरह से समाप्त हो गई हैं, वे बस उपरोक्त को थोड़ा कम थकाऊ बनाते हैं।
ओह और OPENQUERY
. के साथ कुछ अन्य संभावित गोचाओं के लिए , एरलैंड सोमरस्कोग का लेख यहां देखें:
http://www.sommarskog.se/share_data.html#OPENQUERY