如何从sql中的ntext(xml格式)列获取值

时间:2016-12-29 11:30:02

标签: sql sql-server xml tsql type-conversion

我的SQL数据库中有一个名为 Triggers_xml_data 的列,其类型为 ntext 。该列采用 xml 格式,我正在尝试从 xml 的某个部分获取值。我看到这样做的例子没有像这样的列:

declare @fileContent xml
set @fileContent ='<my:Header>
<my:Requestor>Mehrlein, Roswitha</my:Requestor>
<my:RequestorUserName>SJM\MehrlR01</my:RequestorUserName>
<my:RequestorEmail>RMehrlein@SJM.com</my:RequestorEmail>   
<my:HRContact>Roswita  Mehrlein, Beatrice Porta</my:HRContact>
<my:Entity>SJM Germany</my:Entity>
<my:Department>HR/Administration</my:Department>
<my:PositionTitle>Sales Representative</my:PositionTitle>     
<my:JobDescription>x0lGQRQAAAABAAAAAAAAAAAeAQAyAAAAVgBAAAAA=</my:JobDescription>
<my:PositionDepartment>Sales</my:PositionDepartment>'
 
;WITH XMLNAMESPACES ('http://schemas.microsoft.com/office/infopath/2003/myXSD/2005-08-29T12-58-51' as my)
select @fileContent.value('(//my:PositionDepartment)[1]', 'varchar(255)')

但我想选择我的专栏:

Declare @filevalue xml

select de.triggers_xml_data
from dbo.DEPLOYMENT_ENVIRONMENT as de

但是这不起作用,我尝试使用这个@filecontent.value('(//value)[1]','varchar(255)')并使其等于列值,我尝试过它,但我找不到办法来做到这一点。这可能吗?

当我这样做时:

SELECT 
CAST(
    REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '')
  AS XML).value('(triggers/triggerDefinition/config/item/value)[1]', 'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819

我收到了返回的空值。

以下是我的xml的示例:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration xml:space="preserve">

<triggers>
    <defined>true</defined>
    <triggerDefinition>
      <id>1</id>
      <name>After successful deployment</name>
      <userDescription/>
      <isEnabled>true</isEnabled>
      <pluginKey>com.atlassian.bamboo.triggers.atlassian-bamboo-triggers:afterSuccessfulDeployment</pluginKey>
      <triggeringRepositories/>
      <config>
        <item>
          <key>deployment.trigger.afterSuccessfulDeployment.triggeringEnvironmentId</key>
          <value>19234819</value>
        </item>
      </config>
    </triggerDefinition>
  </triggers>
  <bambooDelimiterParsingDisabled>true</bambooDelimiterParsingDisabled>
</configuration>

1 个答案:

答案 0 :(得分:3)

您发布的XML无效。您的代码示例不起作用...如果没有名称空间声明,则不允许使用名称空间前缀。此外,您的示例错过了结束Header - 标记...

我纠正了这个......

DECLARE @yourTbl TABLE(ID INT, YourXML NTEXT);
INSERT INTO @yourTbl VALUES
(1,N'<my:Header xmlns:my="DummyUrl">
<my:Requestor>Mehrlein, Roswitha</my:Requestor>
<my:RequestorUserName>SJM\MehrlR01</my:RequestorUserName>
<my:RequestorEmail>RMehrlein@SJM.com</my:RequestorEmail>   
<my:HRContact>Roswita  Mehrlein, Beatrice Porta</my:HRContact>
<my:Entity>SJM Germany</my:Entity>
<my:Department>HR/Administration</my:Department>
<my:PositionTitle>Sales Representative</my:PositionTitle>     
<my:JobDescription>x0lGQRQAAAABAAAAAAAAAAAeAQAyAAAAVgBAAAAA=</my:JobDescription>
<my:PositionDepartment>Sales</my:PositionDepartment>
</my:Header>');

--Lazy approach
SELECT ID
      ,CAST(CAST(YourXml AS NVARCHAR(MAX)) AS XML).value(N'(//*:PositionDepartment)[1]','nvarchar(max)')
FROM @yourTbl;


--explicit approach
WITH XMLNAMESPACES('DummyUrl' AS my)
SELECT ID
      ,CAST(CAST(YourXml AS NVARCHAR(MAX)) AS XML).value(N'(/my:Header/my:PositionDepartment)[1]','nvarchar(max)')
FROM @yourTbl

一些背景

如果可能,不应该以除XML 之外的其他格式存储XML,而且应该避免NTEXT,因为它自SS2005以来已被删除!

您必须首先将NTEXT投射到NVARCHAR(MAX),而不是将其投射到XML。如果XML无效,则第二个将中断。这意味着:如果XML确实是您发布它的方式,那么这不起作用!

UPDATE:基于字符串的方法,如果XML不起作用

如果您无法将其强制转换为XML,则可以尝试使用

--String based
WITH Casted AS
(
    SELECT ID
          ,CAST(YourXML AS NVARCHAR(MAX)) AS TheXmlAsString
    FROM @yourTbl
)
,WithPosition AS
(
    SELECT Casted.*
          ,CHARINDEX(N'<my:PositionDepartment>',TheXmlAsString) + LEN(N'<my:PositionDepartment>') AS FirstLetter
    FROM Casted
)
SELECT ID 
      ,SUBSTRING(TheXmlAsString,FirstLetter,CHARINDEX('<',TheXmlAsString,FirstLetter)-FirstLetter)
FROM WithPosition

更新2

根据您的编辑,以下内容会返回NULL值。这很好,因为它表明演员阵容是成功的。

SELECT 
CAST(
    REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '')
  AS XML).value('(triggers/triggerDefinition/config/item/value)[1]',
'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819

试试这个(使用通配符跳过命名空间):

SELECT 
CAST(
    REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '')
  AS XML).value('(*:triggers/*:triggerDefinition/*:config/*:item/*:value)[1]', 'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819

这应该更好:

SELECT 
CAST(CAST(de.TRIGGERS_XML_DATA AS NVARCHAR(MAX)) AS XML).value('(*:triggers/*:triggerDefinition/*:config/*:item/*:value)[1]', 'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819

更新3

我宁愿削减完整的声明。您发布的示例将如下所示

DECLARE @DEPLOYMENT_ENVIRONMENT TABLE(ENVIRONMENT_ID INT, TRIGGERS_XML_DATA NTEXT);
INSERT INTO @DEPLOYMENT_ENVIRONMENT VALUES
(19234819,N'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration xml:space="preserve">

<triggers>
    <defined>true</defined>
    <triggerDefinition>
      <id>1</id>
      <name>After successful deployment</name>
      <userDescription/>
      <isEnabled>true</isEnabled>
      <pluginKey>com.atlassian.bamboo.triggers.atlassian-bamboo-triggers:afterSuccessfulDeployment</pluginKey>
      <triggeringRepositories/>
      <config>
        <item>
          <key>deployment.trigger.afterSuccessfulDeployment.triggeringEnvironmentId</key>
          <value>19234819</value>
        </item>
      </config>
    </triggerDefinition>
  </triggers>
  <bambooDelimiterParsingDisabled>true</bambooDelimiterParsingDisabled>
</configuration>');

WITH Casted AS
(
    SELECT CAST(de.TRIGGERS_XML_DATA AS NVARCHAR(MAX)) AS XmlAsSting
    FROM @DEPLOYMENT_ENVIRONMENT as de
    where de.ENVIRONMENT_ID = 19234819
)
SELECT CAST(SUBSTRING(XmlAsSting,CHARINDEX('?>',XmlAsSting)+2,8000) AS XML).value('(/*:configuration/*:triggers/*:triggerDefinition/*:config/*:item/*:value)[1]', 'NVARCHAR(max)') as Item
FROM Casted;