【问题标题】:select and insert records as one xml field选择并插入记录作为一个 xml 字段
【发布时间】:2018-03-19 13:54:41
【问题描述】:

我有两个 1:n 关系的表,在存档数据存储期间,我想将 n 个值存储到一个 xml 字段中。 表格:

  • A(id, description, technology_id...)
  • B(id, A.id, fieldname, value)

我在 Archive 架构上有一个类似于 A 的表,其中包含一个额外的 XML 类型字段,因此 Archive.A 具有所有 dbo.A 字段加一个。我知道我不能一步完成,所以首先我将记录移动到存档表 A,然后从 dbo.B 中选择连接的值,并使用 FOR XML 选择将它们插入到 plus XML 字段中。

第二步的问题在于它会随着消息而死

"非法 xml 字符"

但这对角色是什么或如何找到它没有帮助。

引发错误的更新 SQL 查询:

update aws set workstepdatas = 
    (select tdf.Fieldname Field, wsd.Value [Value] from dbo.worksteps ws
            left join workstepdatas wsd on wsd.WorkStep_Id = ws.id
            left join technologydatafields tdf on tdf.Id = wsd.TechnologyDatafields_Id
            where tdf.fieldname is not null and ws.id = aws.id
            for xml auto)
from archive.worksteps aws
inner join dbo.WorkStepDatas wsd on wsd.workstep_id = aws.id
where aws.id in (select id from @workstepIds);

如果我在没有更新的情况下使用 where ws.id in (select id from @workstepIds) 之类的 where 子句运行选择,则查询运行良好并提供正确的 xml 记录。

如何获取非法字符?为什么当我用 sql server 本身制作 xml 时它有一个非法字符?

更新:

根据@Shnugo 的回答,我有一个有效的一步查询:

insert into archive.worksteps([Id], [Timestamp], [Description], [WorkPlace_Id], [WorkItemState_Id], [UserId], [WorkItem_Id], [Technology_Id], [Failcodes_Id], [DrawingNo], [ManualData], [Deleted], [WorkItemState_Arrival_Id], Workstepdatas)
    select [Id], [Timestamp], [Description], [WorkPlace_Id], [WorkItemState_Id], [UserId], [WorkItem_Id], [Technology_Id], [Failcodes_Id], [DrawingNo], [ManualData], [Deleted], [WorkItemState_Arrival_Id],
        (select tdf.Fieldname Field, wsd.Value [Value] from dbo.workstepdatas wsd
            left join dbo.technologydatafields tdf on tdf.Id = wsd.TechnologyDatafields_Id
            where tdf.fieldname is not null and wsd.WorkStep_Id = ws.Id
                and value NOT LIKE '%[' + CHAR(0)+ '-' +CHAR(31)+']%'  COLLATE Latin1_General_100_BIN2
            for xml auto,type)
    from dbo.worksteps ws
    where ws.WorkItem_Id in (select Id from @workitemIds);

【问题讨论】:

  • 快速拍摄:尝试在xml auto 之后附加, TYPE。所以,让它成为for xml auto, type

标签: sql sql-server tsql


【解决方案1】:

不知道,你真正想达到什么目标,但这是可行的:

一些模型表

DECLARE @tblA TABLE(id INT IDENTITY, SomeValue VARCHAR(100));
DECLARE @tblB TABLE(id INT IDENTITY, aId INT, FieldName VARCHAR(100), FieldValue VARCHAR(100));
INSERT INTO @tblA VALUES('test 1'),('test 2');
INSERT INTO @tblB VALUES(1,'Field 1.1','Val 1.1.'),(1,'Field 1.2','Val 1.2')
                       ,(2,'Field 2.1','Val 2.1.'),(2,'Field 2.2','Val 2.2');

--存档表

DECLARE @tblA_archive TABLE(id INT, SomeValue VARCHAR(100),bXML XML);

--此查询将插入来自@tblA 的所有内容,并将所有相关的@tblB-data 作为 XML 添加到存档表一次性

INSERT INTO @tblA_archive
SELECT a.id
      ,a.SomeValue
      ,(
        SELECT * FROM @tblB AS b 
        WHERE a.id=b.aId
        FOR XML AUTO,TYPE
       )
FROM @tblA AS a;

--结果

SELECT * FROM @tblA_archive;

id  SomeValue   bXML
1   test 1      <b id="1" aId="1" FieldName="Field 1.1" FieldValue="Val 1.1." /><b id="2" aId="1" FieldName="Field 1.2" FieldValue="Val 1.2" />
2   test 2      <b id="3" aId="2" FieldName="Field 2.1" FieldValue="Val 2.1." /><b id="4" aId="2" FieldName="Field 2.2" FieldValue="Val 2.2" />

【讨论】:

  • 没想到一步就能搞定,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 2016-10-01
  • 2016-08-16
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
相关资源
最近更新 更多