【问题标题】:'For Xml Path' in SQL ServerSQL Server 中的“对于 Xml 路径”
【发布时间】:2020-09-17 18:27:11
【问题描述】:

我正在尝试使用“FOR XML PATH”获取以下输出。

<?xml version="1.0" encoding="utf-8"?>
<List Name=”test name”>
    <Columns>
       <c>Column1</c>
       <c>Column2</c>
       <c>Column3</c>
    </Columns>
    <Rows>  
        <r>
            <v>Data1Column1</v>
            <v>Data1Column2</v>
            <v>Data1Column3</v>
        </r>
        <r>
            <v>Data2Column1</v>
            <v>Data2Column2</v>
            <v>Data2Column3</v>
        </r>
    </Rows>
</List>

我正在尝试使用以下内容处理行部分:

SELECT 
    [FA No.] as [v],
    [Location] as [v]
FROM 
    sc.test_rd 
FOR XML PATH (''), ROOT ('Row')

返回以下输出:

<Row>
  <v>6930151128</v>
  <v>6931151128</v>
  <v>6932151128</v>
  <v>6945151990</v>
  <v>6989151838</v>
</Row>

但我需要以下内容:

<Row>
  <v>6930</v><v>151128</v>
  <v>6931</v><v>151128</v>
  <v>6932</v><v>151128</v>
  <v>6945</v><v>151990</v>
  <v>6989</v><v>151838</v>
</Row>

任何帮助将不胜感激。

空值有效,但现在我必须结合 这个

SELECT COLUMN_NAME as [c/*] 
FROM INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME='test_rd'
FOR XML PATH ('') , ROOT ('Columns');

这给了我一个输出:

<Columns>
  <c>id</c>
  <c>FA No.</c>
  <c>Location</c>
  <c>Location Name</c>
  <c>Line of Business</c>
  <c>LOB Name</c>
  <c>Area/CMU/Paypoint</c>
  <c>Model Code</c>
</Columns>

有了这个

SELECT 
[FA No.] as [v],
null,
[Location] as [v],
null,
[Line of Business] as [v],
null,
[Area/CMU/Paypoint] as [v],
null,
[Model Code] as [v]
FROM sc.test_rd
FOR XML path ('r') , Root ('Row')

这给了我这样的输出:

<Row>
  <r>
    <v>6930</v>
    <v>151128</v>
    <v>2100</v>
    <v>2</v>
    <v>CMU3+</v>
  </r>
  <r>
    <v>6931</v>
    <v>151128</v>
    <v>2100</v>
    <v>3</v>
    <v>CMU3+</v>
  </r>
  <r>
    <v>6932</v>
    <v>151128</v>
    <v>2100</v>
    <v>1</v>
    <v>CMU3+</v>
  </r>
  <r>
    <v>6945</v>
    <v>151990</v>
    <v>2100</v>
    <v>2</v>
    <v>CMU3+</v>
  </r>
  <r>
    <v>6989</v>
    <v>151838</v>
    <v>2100</v>
    <v>2</v>
    <v>CMU3+</v>
  </r>
</Row>

所需输出的另一个示例:

<?xml version="1.0" encoding="utf-8"?>
<List Name='test_rd' Action='Update'>
 <Columns><c>FA No.</c><c>Location</c><c>Location Name</c><c>Line of Business</c><c>LOB Name</c><c>Area/CMU/Paypoint</c><c>Model Code</c></Columns>
 <Rows>
<r><v>6930</v><v>151128</v><v>Viewmont Mall</v><v>2100</v><v>Strollers</v><v>1</v><v>CMU3+</v></r>
<r><v>6931</v><v>151128</v><v>Viewmont Mall</v><v>2100</v><v>Strollers</v><v>2</v><v>CMU3+</v></r>
<r><v>6932</v><v>151128</v><v>Viewmont Mall</v><v>2100</v><v>Strollers</v><v>3</v><v>CMU3+</v></r>
<r><v>6933</v><v>151128</v><v>Viewmont Mall</v><v>2100</v><v>Strollers</v><v>4</v><v>CMU3+</v></r>
<r><v>6934</v><v>151128</v><v>Viewmont Mall</v><v>2100</v><v>Strollers</v><v>5</v><v>CMU3+</v></r>

 </Rows>
</List>

我也想添加一个 CASE 选项,但我不断收到错误?

-- test_rd
    SELECT 'test_rd' as [@Name], 'Update' as [@Action]
, (
    SELECT COLUMN_NAME as [c/*] 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME='test_rd' AND TABLE_SCHEMA = 'sc' and  COLUMN_NAME != 'id'
    FOR XML PATH (''), TYPE, ROOT ('Columns')
    )
, (
    SELECT 
        [FA No.] as [v],
        NULL,
        [Location] as [v],
        NULL,
        [Location Name] as [v],
        NULL,
        [Line of Business]as [v],
        NULL,
        [Line of Business Name]as [v],
          CASE WHEN [Line of Business Name] = '0' THEN ''
            WHEN [Line of Business Name] = '1' THEN 'lob1'
            WHEN [Line of Business Name] = '2' THEN 'lob2'
          End as [Line of Business Name],
        NULL,
        [Area/CMU/Paypoint] as [v],
        NULL,
        [Model Code] as [v]
    FROM sc.test_rd
    FOR XML path ('r'), TYPE, ROOT ('Rows')
)
FOR XML PATH('List') 
-- test_rd

查找错误 - SQL Server 数据库错误:列名“业务线名称”包含 FOR XML 要求的无效 XML 标识符; ' '(0x0020) 是第一个错误字符。

【问题讨论】:

  • 为什么[FA No.][Location] 的XML 元素都是&lt;v&gt;?它使 XML 无法解析。似乎其中之一更容易解析:&lt;v id1="6930" id2="151128" /&gt;&lt;v&gt;&lt;id1&gt;6930&lt;/id1&gt;&lt;id2&gt;151128&lt;/id2&gt;&lt;/v&gt;
  • 我同意@JamesL。

标签: sql-server xml tsql xquery


【解决方案1】:

看看下面...注意选择中的NULL

示例

Declare @YourTable Table ([FA No.] varchar(50),[Location] varchar(50))
Insert Into @YourTable Values 
 (6930,151128)
,(6931,151128)
,(6932,151128)
,(6945,151990)
,(6989,151838)
 

SELECT 
[FA No.] as [v],
null,
[Location] as [v]
FROM @YourTable
FOR XML path ('') , Root ('Row')

退货

<Row>
  <v>6930</v>
  <v>151128</v>
  <v>6931</v>
  <v>151128</v>
  <v>6932</v>
  <v>151128</v>
  <v>6945</v>
  <v>151990</v>
  <v>6989</v>
  <v>151838</v>
</Row>

编辑-

有点不清楚您在寻找什么,但您可以在 XML 创建中使用 TYPE 进行子查询。查看Rows = 并注意,TYPE

例子

Select [List/@Name] = YourNameColumn
      ,Rows = ( 
                Select  [FA No.] as [v],
                        null,
                        [Location] as [v]
                 From   sc.test_rd 
                FOR XML path ('') , Root ('Row'),TYPE
              )
  From SomeTable

【讨论】:

  • @Bob 看看编辑。如果您提供示例数据,我相信我们可以得到您想要的结果。
  • 谢谢约翰,我在最初的帖子中添加了所需的输出。
【解决方案2】:

这是一个最小的可重现示例。我使用了 AdventureWorks2012 数据库及其狭窄的三列 Currency 表。

SQL

USE AdventureWorks2012;
GO

SELECT 'test_rd' AS [@Name], 'Update' AS [@Action]
, (
    SELECT COLUMN_NAME as [c/*] 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME='Currency' AND TABLE_SCHEMA = 'Sales' AND COLUMN_NAME != 'CurrencyCode'
    FOR XML PATH (''), TYPE, ROOT ('Columns')
    )
, (
    SELECT TOP(2)
        [CurrencyCode] as [v],
        NULL,
        [Name] as [v],
        NULL,
        [ModifiedDate] as [v]
    FROM Sales.Currency
    FOR XML path ('r'), TYPE, ROOT ('Row')
)
FOR XML PATH('List'), TYPE;

输出

<List Name="test_rd" Action="Update">
  <Columns>
    <c>Name</c>
    <c>ModifiedDate</c>
  </Columns>
  <Row>
    <r>
      <v>AED</v>
      <v>Emirati Dirham</v>
      <v>2002-06-01T00:00:00</v>
    </r>
    <r>
      <v>AFA</v>
      <v>Afghani</v>
      <v>2002-06-01T00:00:00</v>
    </r>
  </Row>
</List>

【讨论】:

  • 完美,但是如何省略第一个列名,对你来说是 CurrencyCode 而对我来说是 id
  • 我该如何改变这个结果:
  • @Bob,在 XML 中,属性值的双引号或单引号没有区别。此外,SQL Server 使用单引号作为字符串的分隔符。这就是为什么在其中使用双引号的原因。
  • 好的,知道了。我还用与 CASE 相关的另一个问题更新了最初的帖子。感谢所有帮助。
  • @Bob,你好像有空位。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
相关资源
最近更新 更多