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

Posted

技术标签:

【中文标题】SQL 或 C#:遍历一个字段的值并插入另一个字段【英文标题】:SQL or C#: Loop through values of one field and insert into another 【发布时间】: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 中。 【参考方案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

【讨论】:

以上是关于SQL 或 C#:遍历一个字段的值并插入另一个字段的主要内容,如果未能解决你的问题,请参考以下文章

雪花我们如何遍历临时表的每一行并将其值插入到另一个表中,其中每个字段的值都是单行?

oracle 把一个字段的值更新另一个字段。

SQL Server 根据字段的值触发插入和/或更新的记录

sql语句从一张表查询一个字段值插入另一个表中

插入数据库表中一条记录同时也插入另一个表中的SQL语句怎么写

循环遍历带有更新字段条件的游标 [PLSQL]