简体   繁体   English

如何在SQL Server导入和导出向导中从XML文件导入?

[英]How to import from XML file in SQL Server Import and Export Wizard?

I have data and schema for a table as a single XML file. 我有一个表的数据和架构作为单个XML文件。 How do I import this using the SQL Server Import and Export Wizard? 如何使用SQL Server导入和导出向导导入它?

Should I use a "Flat File Source" as my Data Source? 我应该使用“平面文件源”作为数据源吗? Or what? 要不然是啥?

[For info, I exported the XML from VistaDB, but I have not yet got as far as the point where the system which created the data might be an issue.] [有关信息,我从VistaDB导出了XML,但是到目前为止,创建数据的系统可能还没有成为问题。

As far as I know, you cannot do this by using a the import export wizard. 据我所知,您不能使用导入导出向导来执行此操作。 Assuming you want the data to wind up all relational rather than as XML datatype, you'll need to create the table and use sp_xml_preparedocument and OPENXML. 假设您希望数据显示所有关系数据而不是XML数据类型,则需要创建表并使用sp_xml_preparedocument和OPENXML。

See How to use OPENXML to load XML data into existing SQL Table? 请参阅如何使用OPENXML将XML数据加载到现有SQL表中?

As far as I know MS SQL Server Management Studio does not have a tool to upload XML to a table. 据我所知,MS SQL Server Management Studio没有将XML上传到表的工具。 There is an option that involves a combination of OPENROWSET and XML processing, but it requires that the files reside in the server's file system. 有一个选项涉及OPENROWSET和XML处理的组合,但是它要求文件位于服务器的文件系统中。

I needed to load into a table a series of log files generated by a Java web Application but had no access to upload them to the server, I had the logs in my local machine. 我需要将Java Web应用程序生成的一系列日志文件加载到表中,但是无权将它们上传到服务器,我将日志保存在本地计算机中。 I managed to upload data in a two step process that is not too cumbersome but its definitely too slow for a permanent solution. 我设法分两个步骤上传数据,这虽然不太麻烦,但是对于永久解决方案来说绝对太慢了。

I created a table that consists of two columns: an autonumeric primary key, and a varchar(max). 我创建了一个由两列组成的表:一个自动数字主键和一个varchar(max)。 I used the import data to upload the text files to the table so that each line in the file is a record in the table. 我使用导入数据将文本文件上载到表,以便文件中的每一行都是表中的一条记录。 The primary key coincidentally represents the line number. 主键同时代表行号。 So I could write something like: 所以我可以这样写:

select LineNumber, TextLine from [LogFile] order by LineNumber

I then prepared another table with an structure that matched the records in my XML. 然后,我准备了另一个表,该表的结构与XML中的记录相匹配。 My XML files had the particularity that each "value" tag was in its own text line, the opening and closing "record" tags where each on a separate line. 我的XML文件的特殊之处在于,每个“值”标记都在其自己的文本行中,而“开始”和“结束”“记录”标记则分别位于单独的行中。

For example: 例如:

    <log>
    <record>
      <date>2018-07-27T09:54:20</date>
      <millis>1532706860250</millis>
      <sequence>13587</sequence>
      <logger>registroweb.ServReg</logger>
      <level>INFO</level>
      <class>somepackage.someclass</class>
      <method>methodname</method>
      <thread>11153</thread>
      <message>some very long text</message>
      <param>another long text</param>
    </record>
   ...
   </log>

This would mean that I could select all records where text_line = '<log>' would give me all opening record tags, but most importantly, self joining the table with t2.line_number = t1.line_number + 1 would always give me the line containing the date tag, line_number+2 would give millis, and so on. 这意味着我可以选择所有记录,其中text_line ='<log>'将给我所有打开的记录标签,但最重要的是,使用t2.line_number = t1.line_number + 1自联接表将始终为我提供包含日期标签line_number + 2将给出毫秒,依此类推。

So with the following query I was able to transform the flat linear table into a proper table: 因此,通过以下查询,我能够将平面线性表转换为适当的表:

insert into LogFileProcessed(
    [date],
    [millis],
    [sequence],
    [logger] ,
    [level]  ,
    [class]  ,
    [method] ,
    [thread] ,
    [message],
    [param]
)
select
    --record.TextLine, 
    convert(datetime, replace(replace(ltrim(dte.TextLine), '<date>',     ''), '</date>',     ''), 126) [date],
    convert(bigint,   replace(replace(ltrim(mls.TextLine), '<millis>',   ''), '</millis>',   '')) [millis],
    convert(bigint,   replace(replace(ltrim(seq.TextLine), '<sequence>', ''), '</sequence>', '')) [sequence],
    replace(replace(ltrim(logr.TextLine),   '<logger>',   ''), '</logger>',   '') [logger],
    replace(replace(ltrim(lvl.TextLine),    '<level>',    ''), '</level>',    '') [level],
    replace(replace(ltrim(cls.TextLine),    '<class>',    ''), '</class>',    '') [class],
    replace(replace(ltrim(mtd.TextLine),    '<method>',   ''), '</method>',   '') [method],
    replace(replace(ltrim(trd.TextLine),    '<thread>',   ''), '</thread>',   '') [thread],
    replace(replace(ltrim(msg.TextLine),    '<message>',  ''), '</message>',  '') [message],
    replace(replace(ltrim(prm.TextLine),    '<param>',    ''), '</param>',    '') [param]  
from LogFile record
left join LogFile dte    on dte.LineNumber    = record.LineNumber+1
left join LogFile mls    on mls.LineNumber    = record.LineNumber+2
left join LogFile seq    on seq.LineNumber    = record.LineNumber+3
left join LogFile logr   on logr.LineNumber   = record.LineNumber+4
left join LogFile lvl    on lvl.LineNumber    = record.LineNumber+5
left join LogFile cls    on cls.LineNumber    = record.LineNumber+6
left join LogFile mtd    on mtd.LineNumber    = record.LineNumber+7
left join LogFile trd    on trd.LineNumber    = record.LineNumber+8
left join LogFile msg    on msg.LineNumber    = record.LineNumber+9
left join LogFile prm    on prm.LineNumber    = record.LineNumber+10 and prm.TextLine <> '</record>' -- param is actually the only tag that is optional and some times is not present in the record.
where record.TextLine = '<record>'
order by 1, 2

Given the particular restrictions I have at the time and the structure of the files, this worked good enough for a one time task, allowing me to perform regular queries on the data without having to repeatedly run XML parsing or processing code. 考虑到我当时的特殊限制和文件的结构,此功能足以完成一项一次性任务,使我可以对数据执行常规查询,而不必重复运行XML解析或处理代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM