Sql-Server

在 TSQL 中使用 XQuery value() 方法時如何避免隱式轉換?

  • February 7, 2021

我有以下使用 TSQL - XQuery 值方法解析的 xml。

<Root>
 <FooAudit>
   <BarIntField>..</BarIntField>
   <BarDateTimeField>..</BarDateTimeField>
   <BarVarcharField>...</BarVarcharField>
   <BarFloatField>...</BarFloatField>              
 </FooAudit>            
</Root>

但是,每次我呼叫 .value() 都會導致隱式轉換。我怎樣才能擺脫這種隱式轉換,因為這個邏輯每分鐘會被呼叫數千次?

SET NOCOUNT ON

DECLARE @BarIntField INT;
DECLARE @BarDateTimeField DATETIME;
DECLARE @BarVarcharField VARCHAR(25);
DECLARE @BarFloatField FLOAT;

--Test with non null values
SET @BarIntField = 123;
SET @BarDateTimeField = GETUTCDATE();
SET @BarVarcharField = 'My Text';
SET @BarFloatField = 2.3;

--Test with null values
/*
SET @BarIntField = NULL;
SET @BarDateTimeField = NULL;
SET @BarVarcharField = NULL;
SET @BarFloatField = NULL;
*/

DECLARE @payload XML;

SET @payload =
(
   SELECT @BarIntField AS BarIntField,
          @BarDateTimeField AS BarDateTimeField,
          @BarVarcharField AS BarVarcharField,
          @BarFloatField AS BarFloatField
   FOR XML PATH('FooAudit'), ROOT('Root'), TYPE
);

--Implicit conversion here
DECLARE @parsedIntValue AS INT = @payload.value('(/Root/FooAudit/BarIntField/text())[1]', 'int');
PRINT @parsedIntValue;

--Implicit conversion here
DECLARE @parsedDateTimeValue AS DATETIME = @payload.value('(/Root/FooAudit/BarDateTimeField/text())[1]', 'DATETIME');
PRINT @parsedDateTimeValue;

--Implicit conversion here
DECLARE @parsedVarcharValue AS VARCHAR(25) = @payload.value('(/Root/FooAudit/BarVarcharField/text())[1]', 'VARCHAR(25)');
PRINT @parsedVarcharValue;

--Implicit conversion here
DECLARE @parsedFloatValue AS FLOAT = @payload.value('(/Root/FooAudit/BarFloatField/text())[1]', 'FLOAT');
PRINT @parsedFloatValue;

這是計劃

您可以忽略隱式轉換警告,它們在這裡無關緊要。但是解析 XML 並不是免費的,而且您正在使用 TSQL 中的最佳方式進行解析。

如果您確實需要改進 XML 解析,則必須嘗試 SQLCLR 和低級XmlReader預編譯的 XmlSerializer

引用自:https://dba.stackexchange.com/questions/284866