SQL Server: OPENXML против SELECT..FROM при работе с XML? - PullRequest
10 голосов
/ 08 марта 2012

У меня есть этот xml:

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

вопрос:

, какой путь предпочтительнее?

Есть ли какие-то преимущества у последнего по сравнению с первым (или наоборот)?

Ответы [ 3 ]

9 голосов
/ 08 марта 2012

Простой тест показывает, что ваш заход на посадку 1 занимает меньше времени, чем заход на посадку 2 .Я бы не стал делать никаких выводов, что это всегда так.Это может зависеть от того, как ваш XML структурирован и как вам нужно запрашивать 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 Server 2005.)

2 голосов
/ 08 марта 2012

Я предпочитаю # 2.попробуйте план выполнения и увидите, что первый подход стоит 97%, тогда как первый стоит только 3%

enter image description here

0 голосов
/ 18 июля 2016
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...