Sql server t-sql创建XML文件,用于XML路径、多级问题

Sql server t-sql创建XML文件,用于XML路径、多级问题,sql-server,tsql,Sql Server,Tsql,我正在创建一个XML文件以上载到第三方产品。文件必须以特定的文件和源信息级别开始,然后是这些事件的事件和机组成员的特定数据要求/级别 我可以使用文件/源信息创建初始级别,并且数据要求与它们应该的完全相同,但是如果初始级别不在每个事件级别之间重复,或者在一个额外的事件级别之间重复,我无法在“根”级别之间的同一个文件中将它们集合在一起。我还设法得到了一个结果,行级别我没有定义,“标记”被修改为和>:,而不是。我做了大量的研究,并尝试使用union方法、子选择、嵌套方法以及FOR XML PATH

我正在创建一个XML文件以上载到第三方产品。文件必须以特定的文件和源信息级别开始,然后是这些事件的事件和机组成员的特定数据要求/级别

我可以使用文件/源信息创建初始级别,并且数据要求与它们应该的完全相同,但是如果初始级别不在每个事件级别之间重复,或者在一个额外的事件级别之间重复,我无法在“根”级别之间的同一个文件中将它们集合在一起。我还设法得到了一个结果,行级别我没有定义,“标记”被修改为
>:
,而不是<>。我做了大量的研究,并尝试使用union方法、子选择、嵌套方法以及FOR XML PATH、AUTO、EXPLICIT、带和不带元素的多种组合。我学到了很多,但我只是没有找到适合我需要的结果的组合

第一个示例是所需的布局。第二个是我的工作中最常见的例子之一,后面是创建它的SQL

应该是什么(FILEINFO级别只有一次,每个事件只有一个事件级别)


这是因为您已经指定了路径“EVENT”。您还可以删除字段名称中的事件,例如,“事件/工作人员/日期\时间\戳记”只能是“工作人员/日期\时间\戳记”

要实现所需的功能,可以使用EVENT元素生成xml,然后插入FILEINFO

DECLARE @x xml;
SET @x=(SELECT 
    [DATE]         AS 'DATE'
    ,[NO]           AS 'NO' 
    ,[DEL_FLAG]         AS 'DEL_FLAG'
    ,[DATE_TIME_STAMP]  AS 'DATE_TIME_STAMP'
    ,'DOE'          as 'CREW/LAST_NAME'
    ,[DEL_FLAG2]        as 'CREW/DEL_FLAG'
    ,[DATE_TIME_STAMP3]     as 'CREW/DATE_TIME_STAMP'
FROM [dbo].XMLForFILEExport x 
FOR XML path('EVENT'), elements,  ROOT('ROOT'))


SET @x.modify('
insert <FILEINFO><SOURCE_ID>P</SOURCE_ID></FILEINFO>
as first
into (/ROOT)[1]');
DECLARE@xxml;
设置@x=(选择
[日期]作为“日期”
,[NO]作为“NO”
,[DEL_FLAG]作为“DEL_FLAG”
,[DATE\u TIME\u STAMP]作为“DATE\u TIME\u STAMP”
“DOE”作为“船员/姓氏”
,[DEL_-FLAG2]作为“船员/DEL_-FLAG”
,[DATE_TIME_STAMP3]作为“船员/日期时间戳”
来自[dbo].XMLForFILEExport x
对于XML路径('EVENT')、元素、根('ROOT'))
设置@x.modify('s)
插入P
首先
进入(/根)[1]';

这是因为您已经指定了路径“EVENT”。您还可以删除字段名称中的事件,例如,“事件/工作人员/日期\时间\戳记”只能是“工作人员/日期\时间\戳记”

要实现所需的功能,可以使用EVENT元素生成xml,然后插入FILEINFO

DECLARE @x xml;
SET @x=(SELECT 
    [DATE]         AS 'DATE'
    ,[NO]           AS 'NO' 
    ,[DEL_FLAG]         AS 'DEL_FLAG'
    ,[DATE_TIME_STAMP]  AS 'DATE_TIME_STAMP'
    ,'DOE'          as 'CREW/LAST_NAME'
    ,[DEL_FLAG2]        as 'CREW/DEL_FLAG'
    ,[DATE_TIME_STAMP3]     as 'CREW/DATE_TIME_STAMP'
FROM [dbo].XMLForFILEExport x 
FOR XML path('EVENT'), elements,  ROOT('ROOT'))


SET @x.modify('
insert <FILEINFO><SOURCE_ID>P</SOURCE_ID></FILEINFO>
as first
into (/ROOT)[1]');
DECLARE@xxml;
设置@x=(选择
[日期]作为“日期”
,[NO]作为“NO”
,[DEL_FLAG]作为“DEL_FLAG”
,[DATE\u TIME\u STAMP]作为“DATE\u TIME\u STAMP”
“DOE”作为“船员/姓氏”
,[DEL_-FLAG2]作为“船员/DEL_-FLAG”
,[DATE_TIME_STAMP3]作为“船员/日期时间戳”
来自[dbo].XMLForFILEExport x
对于XML路径('EVENT')、元素、根('ROOT'))
设置@x.modify('s)
插入P
首先
进入(/根)[1]';

这很简单,只需使用子选择并像处理*普通列一样处理:

此简单的
选择将返回单个

你看,我使用了一个空的
路径()
,但是我设置了
根()

这就是结果

<ROOT>
  <FILEINFO>
    <SOURCE_ID>P</SOURCE_ID>
  </FILEINFO>
</ROOT>
--询问

SELECT 'P' AS [FILEINFO/SOURCE_ID]
      ,(
        SELECT e.[DATE]
              ,e.[NO]
              ,e.EventText
              ,'Doe' AS [CREW/LASTNAME]
        FROM @mockupEventTable e
        FOR XML PATH('EVENT'),TYPE
       ) AS [*] 
FOR XML PATH(''),ROOT('ROOT');
结果

<ROOT>
  <FILEINFO>
    <SOURCE_ID>P</SOURCE_ID>
  </FILEINFO>
  <EVENT>
    <DATE>2019-09-16T00:00:00</DATE>
    <NO>1</NO>
    <EventText>Event 1</EventText>
    <CREW>
      <LASTNAME>Doe</LASTNAME>
    </CREW>
  </EVENT>
  <EVENT>
    <DATE>2019-09-17T00:00:00</DATE>
    <NO>2</NO>
    <EventText>Event 2</EventText>
    <CREW>
      <LASTNAME>Doe</LASTNAME>
    </CREW>
  </EVENT>
</ROOT>

P
2019-09-16T00:00:00
1.
事件1
雌鹿
2019-09-17T00:00:00
2.
事件2
雌鹿
您可以看到,子选择将根据需要创建内部XML。我们必须指定
,键入
,才能将其作为类型化XML。试试同样的方法,但不要。您将得到转义的XML,就像它是简单的文本一样


我将
指定为[*]
(与[node()]
相同)以指示XML“列”没有自己的名称,但应按原样插入。这不是强制性的(请尝试不使用),但它使内容更具可读性…

这很简单,只需使用子选择并像处理*普通列一样处理:

此简单的
选择将返回单个

你看,我使用了一个空的
路径()
,但是我设置了
根()

这就是结果

<ROOT>
  <FILEINFO>
    <SOURCE_ID>P</SOURCE_ID>
  </FILEINFO>
</ROOT>
--询问

SELECT 'P' AS [FILEINFO/SOURCE_ID]
      ,(
        SELECT e.[DATE]
              ,e.[NO]
              ,e.EventText
              ,'Doe' AS [CREW/LASTNAME]
        FROM @mockupEventTable e
        FOR XML PATH('EVENT'),TYPE
       ) AS [*] 
FOR XML PATH(''),ROOT('ROOT');
结果

<ROOT>
  <FILEINFO>
    <SOURCE_ID>P</SOURCE_ID>
  </FILEINFO>
  <EVENT>
    <DATE>2019-09-16T00:00:00</DATE>
    <NO>1</NO>
    <EventText>Event 1</EventText>
    <CREW>
      <LASTNAME>Doe</LASTNAME>
    </CREW>
  </EVENT>
  <EVENT>
    <DATE>2019-09-17T00:00:00</DATE>
    <NO>2</NO>
    <EventText>Event 2</EventText>
    <CREW>
      <LASTNAME>Doe</LASTNAME>
    </CREW>
  </EVENT>
</ROOT>

P
2019-09-16T00:00:00
1.
事件1
雌鹿
2019-09-17T00:00:00
2.
事件2
雌鹿
您可以看到,子选择将根据需要创建内部XML。我们必须指定
,键入
,才能将其作为类型化XML。试试同样的方法,但不要。您将得到转义的XML,就像它是简单的文本一样


我将
指定为[*]
(与[node()]
相同)以指示XML“列”没有自己的名称,但应按原样插入。这不是强制性的(可以不尝试),但它使内容更具可读性…

我明白了,所以允许生成xml,然后简单地插入附加级别。我试试这个,谢谢!虽然这是可行的,但它会迫使您在过程性思维的黑暗山谷中蹒跚前行:-)完全没有必要这样做……我明白了,所以允许生成xml,然后简单地插入额外的级别。我试试这个,谢谢!虽然这是可行的,但它迫使你在程序思维的黑暗山谷中跌跌撞撞:-)绝对没有必要这样做……这完全按照描述的那样工作,而且肯定比我想做的要简单得多。因此,通过更改到第二个“chunk”来使用subselect并在那里定义XML路径,脚本可以在没有为外部部分定义XML路径的情况下运行。看到它很有道理。非常感谢,希望我几天前问过:)这完全按照描述的那样工作,而且肯定比我想做的要简单得多。因此,通过更改到第二个“chunk”来使用subselect并在那里定义XML路径,脚本可以在没有为外部部分定义XML路径的情况下运行。看到它很有道理。非常感谢,但愿我几天前问过:)
<ROOT>
  <FILEINFO>
    <SOURCE_ID>P</SOURCE_ID>
  </FILEINFO>
  <EVENT>
    <DATE>2019-09-16T00:00:00</DATE>
    <NO>1</NO>
    <EventText>Event 1</EventText>
    <CREW>
      <LASTNAME>Doe</LASTNAME>
    </CREW>
  </EVENT>
  <EVENT>
    <DATE>2019-09-17T00:00:00</DATE>
    <NO>2</NO>
    <EventText>Event 2</EventText>
    <CREW>
      <LASTNAME>Doe</LASTNAME>
    </CREW>
  </EVENT>
</ROOT>