2012-03-08 12 views
10

मैं इस xml है:एसक्यूएल सर्वर: OPENXML बनाम चयन ... से एक्सएमएल से निपटने के दौरान?

DECLARE @x XML 
SET @x = 
    '<data> 
     <add>a</add> 
     <add>b</add> 
     <add>c</add> 
    </data>'; 

टास्क:

मैं a,b,c सूचीबद्ध करना चाहते हैं।

दृष्टिकोण 1:

SELECT s.value('.', 'VARCHAR(8000)') AS [ADD] 
FROM @x.nodes('/data/add') AS t(s) 

दृष्टिकोण 2:

DECLARE @idoc INT 
EXEC sp_xml_preparedocument @idoc OUTPUT, @x 

SELECT * 
FROM OPENXML(@idoc, '/data/add', 2) 
     WITH ([add] NVARCHAR(MAX) '.') 

उन दोनों को मुझे दे:

enter image description here

क्ष uestion:

पसंदीदा तरीका कौन सा है?

उत्तरार्द्ध बनाम पूर्व (या उपाध्यक्ष) के कोई फायदे हैं?

+1

मैं व्यक्तिगत रूप से दृष्टिकोण # 1 पसंद करते हैं - यह सा बहुत अधिक मेरे लिए सहज ज्ञान युक्त है, और यह 'sp_xml_preparedocument' आदि के अतिरिक्त कदम की आवश्यकता नहीं है - बस सादे –

+2

@marc_s का उपयोग करना आसान है और इसके साथ ... मतलब # 1 दृश्यों और इस तरह उपयोग किया जा सकता है। –

उत्तर

9

एक साधारण परीक्षण से पता चलता है कि आपके दृष्टिकोण 1दृष्टिकोण 2 की तुलना में कम समय लगता है खर्च होता है। मैं हमेशा इस मामले के बारे में कोई निष्कर्ष नहीं खींचूंगा। यह इस बात पर निर्भर करता है कि आपका एक्सएमएल कैसे संरचित है और आपको XML से पूछताछ करने की आवश्यकता है।

संग्रहित प्रक्रियाओं पर परीक्षण करने के लिए:

create procedure TestXML 
    @X xml 
as 
set nocount on 

select X.N.value('.', 'varchar(8000)') 
from @X.nodes('/root/item') as X(N) 

go 

create procedure TestOpenXML 
    @X xml 
as 
set nocount on 

declare @idoc int 
exec sp_xml_preparedocument @idoc out, @X 

select value 
from openxml(@idoc, '/root/item',1) 
    with (value varchar(8000) '.') 

exec sp_xml_removedocument @idoc 

टेस्ट:

declare @X xml 

set @X = 
    (
    select number as '*' 
    from master..spt_values 
    for xml path('item'), root('root'), type 
) 

set statistics time on 
exec TestXML @X 
exec TestOpenXML @X 

परिणाम दृष्टिकोण 1:

SQL Server Execution Times: 
    CPU time = 63 ms, elapsed time = 70 ms. 

परिणाम दृष्टिकोण 2:

SQL Server Execution Times: 
    CPU time = 156 ms, elapsed time = 159 ms. 

(SQL सर्वर पर परीक्षण किया गया 2005.)

+0

@PraVn उत्तर के विपरीत जूते में कम समय लग सकता है? –

+0

@RoyiNamir - क्वेरी लागत निष्पादन समय के समान नहीं है और जब XML क्वेरी क्वेरी लागत की बात आती है तो विश्वसनीय नहीं होना चाहिए। –

+0

(सिर्फ एक विचार के लिए) - आप इसे कैसे हल करेंगे?http://stackoverflow.com/questions/10818115/cell-to-cell-comparison-in-sql- सर्वर (जवाब परेशान न करें, शब्दों में जवाब दें ...) आपके समय के लिए धन्यवाद। –

2

मैं # 2 पसंद करता हूं। कार्य योजना लागू करके कोशिश करते हैं और देखते हैं कि पहले approch लागत 97% जहां cond के रूप में एक केवल 3%

enter image description here

+1

प्रयास के लिए धन्यवाद: पी। बैच के सापेक्ष 3%। बैच क्या है? अन्य 9 7% कहां हैं? –

+2

मेरी राय में, XML डेटा प्रकार का उपयोग करने पर क्वेरी लागत अनुमान विश्वसनीय नहीं होना चाहिए। –

+1

@RoyiNamir मैं एक बैच में प्रश्नों को tboth भाग गया। पहले के लिए 97% और दूसरे के लिए 3% – PraveenVenu

0
SET NOCOUNT ON; 
DECLARE @BankXml VARCHAR(MAX) = '<ROOT><ITEM BAF="HI" /></ROOT>' 
DECLARE @ErrMsg VARCHAR(MAX) ='',@XmlId INT,@TranCount INT 
CREATE TABLE #tmptbl(BAF VARCHAR(10)) 
IF (@BankXml IS NOT NULL)   
    BEGIN   
     EXEC SP_XML_PREPAREDOCUMENT @XmlId OUTPUT, @BankXml 
     INSERT INTO #tmptbl(BAF) 
     SELECT BAF 
     FROM OPENXML(@XmlId, 'ROOT/ITEM', 1) WITH 
     (
      BAF VARCHAR(10) 
     )       
    END 
BEGIN TRY 
    IF @@TRANCOUNT = 0 
     SET @TranCount = 1 
    IF @TranCount=1 
     BEGIN TRAN 
    IF 1=1 
    BEGIN 
     SELECT BAF FROM #tmptbl 
    END  
    IF @TranCount = 1 
     COMMIT TRAN 
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT = 1 AND @TranCount = 1 
    ROLLBACK TRAN 
    SET @ErrMsg = 'Error : ' + @ErrMsg + ' : ' + ERROR_MESSAGE() 
    RAISERROR(@ErrMsg,16,1) 
END CATCH 
संबंधित मुद्दे