How to avoid implicit conversion when using XQuery value() method in TSQL?
-
15-03-2021 - |
题
I have the following xml that I am parsing using TSQL - XQuery value method.
<Root>
<FooAudit>
<BarIntField>..</BarIntField>
<BarDateTimeField>..</BarDateTimeField>
<BarVarcharField>...</BarVarcharField>
<BarFloatField>...</BarFloatField>
</FooAudit>
</Root>
However, every time I invoke .value() it results in an implicit conversion. How can I get rid of this implicit conversion since this logic will be called thousands of times per minute?
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;
Here is the plan.
解决方案
You can ignore the implicit conversion warnings, they are irrelevant here. But parsing XML is not free, and you're doing it the best way possible in TSQL.
If you really need to improve the XML parsing, you'd have to try SQLCLR and the low-level XmlReader, or a pre-compiled XmlSerializer.
不隶属于 dba.stackexchange