使用通配符的T-SQL xquery .modify方法

时间:2016-04-27 19:03:56

标签: sql-server xml tsql xquery xml-dml

我在SQL Server 2014中工作。我创建了一个存储过程来完成其处理工作,最后,获取最终查询输出并将其格式化为XML。由于过程中逻辑的性质,有时必须从最终的XML输出中删除节点。这是XML输出的示例(为简洁起见,我没有包含根节点;希望他们不需要回答我的问题):

<DALink>
    <InteractingIngredients>
        <InteractingIngredient>
            <IngredientID>1156</IngredientID>
            <IngredientDesc>Lactobacillus acidophilus</IngredientDesc>
            <HICRoot>Lactobacillus acidophilus</HICRoot>
            <PotentiallyInactive>Not necessary</PotentiallyInactive>
            <StatusCode>Live</StatusCode>
        </InteractingIngredient>
    </InteractingIngredients>
    <ActiveProductsExistenceCode>Exist</ActiveProductsExistenceCode>
    <IngredientTypeBasisCode>1</IngredientTypeBasisCode>
    <AllergenMatch>Lactobacillus acidophilus</AllergenMatch>
    <AllergenMatchType>Ingredient</AllergenMatchType>
</DALink>
<ScreenDrug>
    <DrugID>1112894</DrugID>
    <DrugConceptType>RxNorm_SemanticClinicalDr</DrugConceptType>
    <DrugDesc>RxNorm LACTOBACILLUS ACIDOPHILUS/PECTIN ORAL capsule</DrugDesc>
    <Prospective>true</Prospective>
</ScreenDrug>

在程序中我有代码,它查看上面的XML结构并删除不应该存在的节点,因为修改xml比调整查询输出更容易。以下是该代码的示例:

SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="OneThing"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="AnotherThing"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="SomethingElse"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="SomethingElseAgain"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="RxNorm*"]');

最后的命令是我无法弄清楚如何工作的命令。我需要做的就是查找“DrugConceptType”元素以字符串“RxNorm”开头的实例,因为可能会出现多个字符串版本。

我已经谷歌和StackOverFlowed详细,但也许是因为我在这方面缺乏经验,我没有正确地提出这个问题。

是否有一种相对简单的方法可以重写上面的最终.modify语句,以便在“RxNorm”之后使用通配符?

1 个答案:

答案 0 :(得分:1)

您的减少根节点是一个问题,因为您正在使用名称空间“ccxsd”,而您的XML没有显示此内容。

无论如何,比写declare namespace ...一遍又一遍更好,这是你的陈述的第一行:

;WITH XMLNAMESPACES('http://schemas.fdbhealth.com/CC/v1_3' AS ccxsd)

好吧,因为.modify()是一个一个语句调用,它不会产生这样的差异......

但是你的通配符

的问题

这将删除所有节点,其中Element的内容以“RxNorm”开头:

SET @xml.modify('delete //*[fn:substring(.,1,6)="RxNorm"]');

请注意缺少名称空间......无法测试...

编辑:一个简化的工作示例:

您必须使用实际的XML(使用root和命名空间)来检查它

DECLARE @xml_Out XML=
'<DALink>
    <InteractingIngredients>
        <InteractingIngredient>
            <IngredientID>1156</IngredientID>
            <IngredientDesc>Lactobacillus acidophilus</IngredientDesc>
            <HICRoot>Lactobacillus acidophilus</HICRoot>
            <PotentiallyInactive>Not necessary</PotentiallyInactive>
            <StatusCode>Live</StatusCode>
        </InteractingIngredient>
    </InteractingIngredients>
    <ActiveProductsExistenceCode>Exist</ActiveProductsExistenceCode>
    <IngredientTypeBasisCode>1</IngredientTypeBasisCode>
    <AllergenMatch>Lactobacillus acidophilus</AllergenMatch>
    <AllergenMatchType>Ingredient</AllergenMatchType>
</DALink>
<ScreenDrug>
    <DrugID>1112894</DrugID>
    <DrugConceptType>RxNorm_SemanticClinicalDr</DrugConceptType>
    <DrugDesc>RxNorm LACTOBACILLUS ACIDOPHILUS/PECTIN ORAL capsule</DrugDesc>
    <Prospective>true</Prospective>
</ScreenDrug>';

SET @xml_Out.modify('delete //InteractingIngredients[fn:substring((../../ScreenDrug/DrugConceptType)[1],1,6)="RxNorm"]');

SELECT @xml_Out;