SQL或C#:循环遍历一个字段的值并插入另一个字段

时间:2011-04-28 12:24:00

标签: c# sql xml

这是名为objects:

的表的名为DataFields的字段中的值
<data><styleid>287634</styleid><c1001>S</c1001><c1002>S</c1002><c1004>S</c1004></data>

我需要这样做:

Select into objectsindex (product, typeid, classid, objectid, FieldName, FieldValue)

Values

select
product,
typeid,
classid,
objectid,
FieldName = 'c1001',
FieldValue = CONVERT(xml, DataFields).value('(/data/c1001/node())[1]', 'nvarchar(1)')
from objects where typeid = 45

表示该字段中的每个XML节点(<data></data><styleid></styleid>节点除外)以及对象表中typeid = 45的每个记录。

'c1001'和/ c1001 /值是可变的,需要从DataFields字段中提取。

我把c#放在标题中因为我假设很多人会告诉我这不仅仅是SQL的工作。但我知道有一些真正的SQL Geniuses,所以我希望有一个SQL解决方案。

3 个答案:

答案 0 :(得分:2)

XQuery救援!试试这个 -

DECLARE @X XML = '<data><styleid>287634</styleid><c1001>S</c1001><c1002>S</c1002><c1004>S</c1004></data>';

WITH T AS (
  SELECT CONVERT(VarChar(100), X.query('local-name(.)')) NodeName,
         X.value('.', 'VarChar(100)') NodeValue
  FROM @X.nodes('//*') F(X)
)
SELECT *
FROM T
WHERE NodeName LIKE 'C%';

这将获取您的数据,从那里我认为INSERT应该是微不足道的。 =)

答案 1 :(得分:1)

..既然你提到了C#,那么你可以用LINQ片段来实现它。

您可以选择LINQPad(http://www.linqpad.net免费)并直接运行,而无需为其创建一个全新的项目。

var objects45 = Objects.Where(obj=>obj.Typeid=="45");
foreach(var obj in objects45) {
    var xml = XElement.Parse(obj.Datafields);
    var fields = xml.Elements().Where(e=>e.Name != "styleid");
    var newRecords = from fieldTag in xml.Elements()
                    where fieldTag.Name != "styleid"
                    select new ObjectsIndex() {
                        Product = obj.Product,
                        Typeid = obj.Typeid,
                        Classid = obj.Classid,
                        Objectid = obj.Objectid,
                        Fieldname = fieldTag.Name.LocalName,
                        Fieldvalue = fieldTag.Value
                    };
    newRecords.Dump("These records will be inserted:");
    // Uncomment to actually insert
    // ObjectsIndexes.InsertAllOnSubmit(newRecords);
}
// Uncomment to actually insert
// ObjectsIndexes.Context.SubmitChanges();

答案 2 :(得分:0)

declare @XML xml = 
'<data>
   <styleid>287634</styleid>
   <c1001>S</c1001>
   <c1002>S</c1002>
   <c1004>S</c1004>
 </data>'

declare @T table (TypeID int, XMLCol xml)
insert into @T values (45, @XML)
insert into @T values (46, @XML)

select
  T.TypeID,
  C.Name,
  D.Item.value('.', 'varchar(max)') as Value
from @T as T
  cross apply T.XMLCol.nodes('/data/*') as D(Item)
  cross apply (select D.Item.value('local-name(.)', 'varchar(max)')) as C(Name)
where
  C.Name <> 'styleid' and
  T.TypeID = 45

结果

TypeID  Name   Value
45      c1001  S
45      c1002  S
45      c1004  S

另一个版本

select
  T.TypeID,
  D.Item.value('local-name(.)', 'varchar(max)') as Name,
  D.Item.value('.', 'varchar(max)') as Value
from @T as T
  cross apply T.XMLCol.nodes('/data/*[local-name(.)!="styleid"]') as D(Item)
where
  T.TypeID = 45