चर में sp_executesql परिणाम कैसे प्राप्त करें?


178

मेरे पास गतिशील एसक्यूएल का एक टुकड़ा है जिसे मुझे निष्पादित करने की आवश्यकता है, मुझे परिणाम को एक चर में संग्रहीत करने की आवश्यकता है।

मुझे पता है कि मैं इसका उपयोग कर सकता हूं sp_executesqlलेकिन यह कैसे करें इसके बारे में स्पष्ट उदाहरण नहीं मिल सकते हैं।

जवाबों:


253

यदि आपके पास OUTPUT पैरामीटर हैं तो आप कर सकते हैं

DECLARE @retval int   
DECLARE @sSQL nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);

DECLARE @tablename nvarchar(50)  
SELECT @tablename = N'products'  

SELECT @sSQL = N'SELECT @retvalOUT = MAX(ID) FROM ' + @tablename;  
SET @ParmDefinition = N'@retvalOUT int OUTPUT';

EXEC sp_executesql @sSQL, @ParmDefinition, @retvalOUT=@retval OUTPUT;

SELECT @retval;

लेकिन अगर आप एसपी को संशोधित नहीं कर सकते हैं और नहीं कर सकते हैं:

-- Assuming that your SP return 1 value
create table #temptable (ID int null)
insert into #temptable exec mysp 'Value1', 'Value2'
select * from #temptable

सुंदर नहीं है, लेकिन काम करता है।


मेरा sp
JohnIdol

1
@retvalOUT=@retval OUTPUT? sp_executesqlबस के तीसरे पैरामीटर नहीं होना चाहिए @retval OUTPUT?
मोहम्मद देहगन

2
बस एक सामान्य प्रश्न, एक से अधिक प्रश्नों के बारे में क्या? क्वेरी कैसा दिखेगा?
श्रीवास्तव

3
@SrivastavReddy मुझे यह नहीं मिला कि यह उत्तर इस तरह कैसे मिल सकता है। निशांत के जवाब की जाँच करें ..
'12

2
मुझे लगता है कि यह सही है:EXEC sp_executesql @sSQL, @ParmDefinition, @retval OUTPUT;
इयान

50
DECLARE @tab AS TABLE (col1 VARCHAR(10), col2 varchar(10)) 
INSERT into @tab EXECUTE  sp_executesql N'
SELECT 1 AS col1, 2 AS col2
UNION ALL
SELECT 1 AS col1, 2 AS col2
UNION ALL
SELECT 1 AS col1, 2 AS col2'

SELECT * FROM @tab

मैंने पहले इस विधि का उपयोग किया है। यह केवल पहले पर काम करने लगता है insert into @tab। यदि आप अलग-अलग sql के साथ insert into @tabकई को चलाने और चलाने की कोशिश करते हैं execute sp_executesql, तो select * from @tabकेवल पहले निष्पादित के परिणाम दिखाता है
माइक कॉसर

उफ़, मेरी बुर। मेरे दूसरे चयन में एक त्रुटि थी, जिसका अर्थ था कि यह शून्य पंक्तियों को वापस कर रहा था। यह विधि बहुत अच्छा काम करती है, और इसके लिए एक अस्थायी तालिका की आवश्यकता नहीं होती है!
माइक कॉसर

यह सबसे अच्छा जवाब है। हालाँकि मुझे डायनेमिक SQL चलाने की आवश्यकता थी, जिसका अर्थ है कि आपको पहले अपने डायनेमिक SQL को एक पैरामीटर में बनाना होगा अर्थात पहले Decare @SQL nvarchar (255) = N'Select 20 '- उसके बाद बस sl_executeSql पैरामीटर को पास करना होगा।
जोश हैरिस

यह समाधान सबसे अच्छा एक है, मैंने कई अन्य लोगों की कोशिश की और यह केवल एक ही है जिसने मेरे लिए काम किया। धन्यवाद निशांत
एमएमईएल

40
DECLARE @vi INT
DECLARE @vQuery NVARCHAR(1000)

SET @vQuery = N'SELECT @vi= COUNT(*) FROM <TableName>'

EXEC SP_EXECUTESQL 
        @Query  = @vQuery
      , @Params = N'@vi INT OUTPUT'
      , @vi = @vi OUTPUT

SELECT @vi

8
चर viOUTPUT और viINT की घोषणा कहां है?
जेसन मार्तजया

1
यह एक मेरे लिए काम किया। अधिक मतों के साथ उत्तर नहीं दिया गया
sh_kamalh 15

5
पैरामीटर @vQuery को NVARCHAR नहीं VARCHAR के रूप में घोषित किया जाना चाहिए
फ़रज़ाद करीमी


3

रिटर्न मान आमतौर पर परिणाम "वापस" करने के लिए उपयोग नहीं किया जाता है, लेकिन सफलता (0) या त्रुटि संख्या (1-65K) वापस करने के लिए। उपरोक्त सभी संकेत देते हैं कि sp_executesql मान वापस नहीं करता है, जो सही नहीं है। sp_executesql सफलता के लिए 0 और विफलता के लिए कोई अन्य नंबर लौटाएगा।

नीचे में, @i 2727 लौटेगा

DECLARE @s NVARCHAR(500)
DECLARE @i INT;
SET @s = 'USE [Blah]; UPDATE STATISTICS [dbo].[TableName] [NonExistantStatisticsName];';
EXEC @i = sys.sp_executesql @s
SELECT @i AS 'Blah'

SSMS इस Msg 2727, लेवल 11, स्टेट 1, लाइन 1 को 'NonExistantStaticsName' इंडेक्स नहीं खोजेगा।


2

DECLARE @ValueTable टेबल (मूल्य वर्कर (100))

                    SELECT @sql = N'SELECT SRS_SizeSetDetails.'+@COLUMN_NAME+' FROM SRS_SizeSetDetails WHERE FSizeID = '''+@FSizeID+''' AND SRS_SizeSetID = '''+@SRS_SizeSetID+'''';

                    INSERT INTO @ValueTable
                    EXEC sp_executesql @sql;

                    SET @Value='';

                    SET @Value = (SELECT TOP 1  Value FROM @ValueTable)

                    DELETE FROM @ValueTable

2

यदि आप 1 से अधिक मान लौटना चाहते हैं, तो इसका उपयोग करें:

DECLARE @sqlstatement2      NVARCHAR(MAX);
DECLARE @retText            NVARCHAR(MAX);  
DECLARE @ParmDefinition     NVARCHAR(MAX);
DECLARE @retIndex           INT = 0;

SELECT @sqlstatement = 'SELECT @retIndexOUT=column1 @retTextOUT=column2 FROM XXX WHERE bla bla';

SET @ParmDefinition = N'@retIndexOUT INT OUTPUT, @retTextOUT NVARCHAR(MAX) OUTPUT';

exec sp_executesql @sqlstatement, @ParmDefinition, @retIndexOUT=@retIndex OUTPUT, @retTextOUT=@retText OUTPUT;

लौटे मान @retIndex और @retText में हैं


1

यहाँ कुछ आप कोशिश कर सकते हैं

DECLARE  @SqlStatement  NVARCHAR(MAX) = ''
       ,@result     XML
       ,@DatabaseName  VARCHAR(100)
       ,@SchemaName    VARCHAR(10)
       ,@ObjectName    VARCHAR(200);

SELECT   @DatabaseName = 'some database'
       ,@SchemaName   = 'some schema'
       ,@ObjectName   = 'some object (Table/View)'

SET @SqlStatement = '
                    SELECT @result = CONVERT(XML,
                                            STUFF( ( SELECT *
                                                     FROM 
                                                       (
                                                          SELECT TOP(100) 
                                                          * 
                                                          FROM ' + QUOTENAME(@DatabaseName) +'.'+ QUOTENAME(@SchemaName) +'.' + QUOTENAME(@ObjectName) + '
                                                       ) AS A1 
                                                    FOR XML PATH(''row''), ELEMENTS, ROOT(''recordset'')
                                                 ), 1, 0, '''')
                                       )
                ';

EXEC sp_executesql @SqlStatement,N'@result XML OUTPUT', @result = @result OUTPUT;

SELECT DISTINCT
    QUOTENAME(r.value('fn:local-name(.)', 'VARCHAR(200)')) AS ColumnName
FROM @result.nodes('//recordset/*/*') AS records(r)
ORDER BY ColumnName

0

यह एक लंबे समय से पहले था, इसलिए यदि यह अभी भी आवश्यक है, तो सुनिश्चित न करें, लेकिन आप @@ ROWCOUNT चर का उपयोग यह देखने के लिए कर सकते हैं कि पिछले sql कथन से कितनी पंक्तियाँ प्रभावित हुई थीं।

यह तब सहायक होता है जब उदाहरण के लिए आप एक गतिशील अपडेट स्टेटमेंट का निर्माण करते हैं और इसे निष्पादन के साथ चलाते हैं। @@ ROWCOUNT दिखाएगा कि कितनी पंक्तियों को अपडेट किया गया था।

यहाँ परिभाषा है


0

यह मेरे लिए काम किया:

DECLARE @SQL NVARCHAR(4000)

DECLARE @tbl Table (
    Id int,
    Account varchar(50),
    Amount int
) 

-- Lots of code to Create my dynamic sql statement

insert into @tbl EXEC sp_executesql @SQL

select * from @tbl
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.