选择并将记录作为一个xml字段插入

时间:2018-03-19 13:54:42

标签: sql sql-server tsql

我在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选择的加号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 where ws.id in (select id from @workstepIds)之类的子句运行没有更新的select,则查询运行正常并提供正确的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);

1 个答案:

答案 0 :(得分:2)

不知道,你真正想要实现的目标,但这有效:

一些模型表

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 - 数据作为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" />