【发布时间】:2014-03-09 22:17:35
【问题描述】:
我有一个表的数据和架构作为单个 XML 文件。如何使用 SQL Server 导入和导出向导导入它?
我应该使用“平面文件源”作为我的数据源吗?还是什么?
[关于信息,我从 VistaDB 中导出了 XML,但我还没有达到创建数据的系统可能存在问题的程度。]
【问题讨论】:
标签: sql-server vistadb sql-import-wizard
我有一个表的数据和架构作为单个 XML 文件。如何使用 SQL Server 导入和导出向导导入它?
我应该使用“平面文件源”作为我的数据源吗?还是什么?
[关于信息,我从 VistaDB 中导出了 XML,但我还没有达到创建数据的系统可能存在问题的程度。]
【问题讨论】:
标签: sql-server vistadb sql-import-wizard
据我所知,您无法使用导入导出向导来执行此操作。假设您希望数据以所有关系而不是 XML 数据类型结束,您需要创建表并使用 sp_xml_preparedocument 和 OPENXML。
见How to use OPENXML to load XML data into existing SQL Table?
【讨论】:
据我所知,MS SQL Server Management Studio 没有将 XML 上传到表的工具。 有一个选项涉及 OPENROWSET 和 XML 处理的组合,但它要求文件驻留在服务器的文件系统中。
我需要将 Java Web 应用程序生成的一系列日志文件加载到表中,但无法将它们上传到服务器,我在本地机器上有日志。我设法分两步上传数据,这不是太麻烦,但对于永久解决方案来说肯定太慢了。
我创建了一个包含两列的表:一个自动数字主键和一个 varchar(max)。 我使用导入数据将文本文件上传到表中,这样文件中的每一行都是表中的一条记录。主键恰好代表行号。 所以我可以写这样的东西:
select LineNumber, TextLine from [LogFile] order by LineNumber
然后我准备了另一个表,其结构与我的 XML 中的记录相匹配。 我的 XML 文件的特点是每个“值”标签都在自己的文本行中,开始和结束“记录”标签在单独的一行中。
例如:
<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>
这意味着我可以选择 text_line = '
因此,通过以下查询,我能够将平面线性表转换为合适的表:
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
考虑到我当时的特定限制和文件结构,这对于一次性任务来说已经足够好,允许我对数据执行定期查询,而无需重复运行 XML 解析或处理代码。
【讨论】: