2011-04-28 53 views
2

這就是所謂的表中的數據域稱爲對象的字段中的值:SQL或C#:遍歷一個字段的值,並插入到另一個

<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 

在該領域(除了<data></data><styleid></styleid>和節點)的每個XML節點和對象表,其中typeid的= 45。

在「C1001」和/ C1001 /值的每個記錄變量需要從DataFields字段中提取。

我在標題中放了c#,因爲我認爲很多人會告訴我這不僅僅是SQL的工作。但我知道有一些真正的SQL Geniuses,所以我希望有一個SQL解決方案。

+0

嘗試重新標記XQuery。由於節點名稱是可變的,因此可能會有解決方案使用可以將其全部保留在T-SQL中的解決方案。 – Yuck 2011-04-28 12:27:30

回答

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

+0

忘了提及,我正在使用SQL 2K8,所以如果您至少沒有使用該版本,內聯變量分配將不起作用。並且// *並不是獲得您要查找的節點的非常有效的方法。隨着XML文檔的更好的瞭解,您可以更加選擇性地使用所需的節點。 – Yuck 2011-04-28 12:38:54

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 
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(); 
相關問題