TSQL XML 将节点值转换为 int
TSQL XML Convert node value to int
我在 TSQL 中有 XML,
Declare @xml XML = '<soap:Envelope xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com" xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com" xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<upsertList>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xsi:type="q1:CustomRecord" externalId="F95C35CF-950E-4756-8C33-43CA0C47FF45">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="25"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1849"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>6.00</value>
</customField>
</q1:customFieldList>
</q1:record>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" externalId="D596F4DB-D7FE-409A-9D40-916FF88FB188">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="24"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1902"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>2.00</value>
</customField>
</q1:customFieldList>
</q1:record>
</upsertList>
</soap:Body>
</soap:Envelope>'
现在,我想找到 customField 的属性 => xsi:type="LongCustomFieldRef" 然后将值更新为整数。
意思是我想要 Integer: 6 而不是 6.00
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>6</value>
</customField>
我不知道,你为什么需要这个。带有 .00
的数字可以毫无问题地转换为 int。如果这主要是装饰性的,我不会碰这个......如果你需要这个(可能是由于非常严格的架构检查),你可以走这条路,但这并不简单:
您可能知道,XML 的 .modify()
每次调用只能更新一个值。这是相当有限的。
如果您的结构始终相同,您可以使用 CTE
将其切碎并从头开始 re-construct XML。但这可能会给您的命名空间带来新的麻烦。
你可以试试这个:
--你的Xml
DECLARE @xml XML = '<soap:Envelope xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com"
xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com"
xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com" xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<upsertList>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xsi:type="q1:CustomRecord" externalId="F95C35CF-950E-4756-8C33-43CA0C47FF45">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="25"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1849"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>6.00</value>
</customField>
</q1:customFieldList>
</q1:record>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" externalId="D596F4DB-D7FE-409A-9D40-916FF88FB188">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="24"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1902"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>2.00</value>
</customField>
</q1:customFieldList>
</q1:record>
</upsertList>
</soap:Body>
</soap:Envelope>';
--写入临时文件table
SELECT @xml AS TheXml INTO #tmpXml;
--读取给定xsi:type
的所有值,其中值包含dot
--注意:您的customFieldList
定义了一个新的default命名空间!
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS [soap]
,'urn:customization_2015_2.setup.webservices.netsuite.com' AS q1
,'http://www.w3.org/2001/XMLSchema-instance' as xsi
,'urn:core_2015_2.platform.webservices.netsuite.com' AS innerDflt)
SELECT r.value('@externalId','uniqueidentifier') AS Record_ExternalId
,cf.value('@scriptId','nvarchar(max)') AS CustomField_ScriptId
,cf.value('(innerDflt:value/text())[1]','decimal(10,4)') AS OriginalValue
,CAST(cf.value('(innerDflt:value/text())[1]','decimal(10,4)') AS INT) AS CastedValue
INTO #tmpValues
FROM #tmpXml
CROSS APPLY TheXml.nodes('/soap:Envelope
/soap:Body
/upsertList
/q1:record') AS A(r)
CROSS APPLY A.r.nodes('q1:customFieldList
/innerDflt:customField[@xsi:type="LongCustomFieldRef" and innerDflt:value[contains(text()[1],".")]]') AS B(cf);
--中间结果
SELECT * FROM #tmpXml
SELECT * FROM #tmpValues;
--使用 CURSOR
读取行和 .modify()
替换 "wrong" 值。
DECLARE @rId NVARCHAR(MAX), @fId NVARCHAR(MAX), @v NVARCHAR(MAX);
DECLARE cur CURSOR FOR SELECT Record_ExternalId
,CustomField_ScriptId
,CAST(CastedValue AS NVARCHAR(MAX))
FROM #tmpValues;
OPEN cur;
FETCH NEXT FROM cur INTO @rId,@fId,@v;
WHILE @@FETCH_STATUS=0
BEGIN
WITH XMLNAMESPACES( 'http://schemas.xmlsoap.org/soap/envelope/' AS [soap]
,'urn:customization_2015_2.setup.webservices.netsuite.com' AS q1
,'http://www.w3.org/2001/XMLSchema-instance' as xsi
,'urn:core_2015_2.platform.webservices.netsuite.com' AS innerDflt)
UPDATE #tmpXml SET TheXml.modify('replace value of (/soap:Envelope
/soap:Body
/upsertList
/q1:record[@externalId=sql:variable("@rId")]
/q1:customFieldList
/innerDflt:customField[@scriptId=sql:variable("@fId")]
/innerDflt:value
/text())[1] with sql:variable("@v")');
FETCH NEXT FROM cur INTO @rId,@fId,@v;
END
CLOSE cur;
DEALLOCATE cur;
--重置@xml
SET @xml=(SELECT TheXml FROM #tmpXml);
--最终结果
SELECT @xml;
我在 TSQL 中有 XML,
Declare @xml XML = '<soap:Envelope xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com" xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com" xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<upsertList>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xsi:type="q1:CustomRecord" externalId="F95C35CF-950E-4756-8C33-43CA0C47FF45">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="25"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1849"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>6.00</value>
</customField>
</q1:customFieldList>
</q1:record>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" externalId="D596F4DB-D7FE-409A-9D40-916FF88FB188">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="24"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1902"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>2.00</value>
</customField>
</q1:customFieldList>
</q1:record>
</upsertList>
</soap:Body>
</soap:Envelope>'
现在,我想找到 customField 的属性 => xsi:type="LongCustomFieldRef" 然后将值更新为整数。 意思是我想要 Integer: 6 而不是 6.00
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>6</value>
</customField>
我不知道,你为什么需要这个。带有 .00
的数字可以毫无问题地转换为 int。如果这主要是装饰性的,我不会碰这个......如果你需要这个(可能是由于非常严格的架构检查),你可以走这条路,但这并不简单:
您可能知道,XML 的 .modify()
每次调用只能更新一个值。这是相当有限的。
如果您的结构始终相同,您可以使用 CTE
将其切碎并从头开始 re-construct XML。但这可能会给您的命名空间带来新的麻烦。
你可以试试这个:
--你的Xml
DECLARE @xml XML = '<soap:Envelope xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com"
xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com"
xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xmlns:urn1="urn:core_2015_2.platform.webservices.netsuite.com" xmlns:urn="urn:messages_2015_2.platform.webservices.netsuite.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<upsertList>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" xsi:type="q1:CustomRecord" externalId="F95C35CF-950E-4756-8C33-43CA0C47FF45">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="25"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1849"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>6.00</value>
</customField>
</q1:customFieldList>
</q1:record>
<q1:record xmlns:q1="urn:customization_2015_2.setup.webservices.netsuite.com" externalId="D596F4DB-D7FE-409A-9D40-916FF88FB188">
<q1:recType internalId="12" type="customRecord"/>
<q1:customFieldList xmlns="urn:core_2015_2.platform.webservices.netsuite.com">
<customField scriptId="custrecord_sps_content_package" xsi:type="SelectCustomFieldRef">
<value internalId="24"/>
</customField>
<customField scriptId="custrecord_sps_content_item" xsi:type="SelectCustomFieldRef">
<value internalId="1902"/>
</customField>
<customField scriptId="custrecord_sps_content_qty" xsi:type="LongCustomFieldRef">
<value>2.00</value>
</customField>
</q1:customFieldList>
</q1:record>
</upsertList>
</soap:Body>
</soap:Envelope>';
--写入临时文件table
SELECT @xml AS TheXml INTO #tmpXml;
--读取给定xsi:type
的所有值,其中值包含dot
--注意:您的customFieldList
定义了一个新的default命名空间!
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS [soap]
,'urn:customization_2015_2.setup.webservices.netsuite.com' AS q1
,'http://www.w3.org/2001/XMLSchema-instance' as xsi
,'urn:core_2015_2.platform.webservices.netsuite.com' AS innerDflt)
SELECT r.value('@externalId','uniqueidentifier') AS Record_ExternalId
,cf.value('@scriptId','nvarchar(max)') AS CustomField_ScriptId
,cf.value('(innerDflt:value/text())[1]','decimal(10,4)') AS OriginalValue
,CAST(cf.value('(innerDflt:value/text())[1]','decimal(10,4)') AS INT) AS CastedValue
INTO #tmpValues
FROM #tmpXml
CROSS APPLY TheXml.nodes('/soap:Envelope
/soap:Body
/upsertList
/q1:record') AS A(r)
CROSS APPLY A.r.nodes('q1:customFieldList
/innerDflt:customField[@xsi:type="LongCustomFieldRef" and innerDflt:value[contains(text()[1],".")]]') AS B(cf);
--中间结果
SELECT * FROM #tmpXml
SELECT * FROM #tmpValues;
--使用 CURSOR
读取行和 .modify()
替换 "wrong" 值。
DECLARE @rId NVARCHAR(MAX), @fId NVARCHAR(MAX), @v NVARCHAR(MAX);
DECLARE cur CURSOR FOR SELECT Record_ExternalId
,CustomField_ScriptId
,CAST(CastedValue AS NVARCHAR(MAX))
FROM #tmpValues;
OPEN cur;
FETCH NEXT FROM cur INTO @rId,@fId,@v;
WHILE @@FETCH_STATUS=0
BEGIN
WITH XMLNAMESPACES( 'http://schemas.xmlsoap.org/soap/envelope/' AS [soap]
,'urn:customization_2015_2.setup.webservices.netsuite.com' AS q1
,'http://www.w3.org/2001/XMLSchema-instance' as xsi
,'urn:core_2015_2.platform.webservices.netsuite.com' AS innerDflt)
UPDATE #tmpXml SET TheXml.modify('replace value of (/soap:Envelope
/soap:Body
/upsertList
/q1:record[@externalId=sql:variable("@rId")]
/q1:customFieldList
/innerDflt:customField[@scriptId=sql:variable("@fId")]
/innerDflt:value
/text())[1] with sql:variable("@v")');
FETCH NEXT FROM cur INTO @rId,@fId,@v;
END
CLOSE cur;
DEALLOCATE cur;
--重置@xml
SET @xml=(SELECT TheXml FROM #tmpXml);
--最终结果
SELECT @xml;