【问题标题】:SQL or C#: Loop through values of one field and insert into anotherSQL 或 C#:遍历一个字段的值并插入另一个字段
【发布时间】:2011-08-14 16:21:46
【问题描述】:

这是一个名为 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 节点(除了 &lt;data&gt;&lt;/data&gt;&lt;styleid&gt;&lt;/styleid&gt; 节点)以及对象表中 typeid = 45 的每条记录。

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

我将 c# 放在标题中是因为我想你们中的许多人会告诉我这不仅仅是 SQL 的工作。但我知道那里有一些真正的 SQL Geniuses,所以我希望有一个 SQL 解决方案。

【问题讨论】:

  • 也尝试为 XQuery 重新标记。由于节点名称是可变的,因此可能有一个解决方案可以将其全部保存在 T-SQL 中。

标签: c# sql xml


【解决方案1】:

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 应该是微不足道的。 =)

【讨论】:

  • 忘了提,我使用的是 SQL 2K8,所以如果你不是至少在那个版本,内联变量分配将不起作用。并且 //* 不是获取您正在寻找的节点的非常有效的方法。通过更好地了解 XML 文档,您可以更有选择性地选择所需的节点。
【解决方案2】:

..既然你提到了 C#,下面是你如何使用 LINQ sn-p 来做的。

您可以选择 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();

【讨论】:

    【解决方案3】:
    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 1970-01-01
      • 2012-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多