2011-11-08 13 views
5

Aşağıdaki XML bloğunu, istenen düzene göre (aşağıda) SQL Server tablosuna ayrıştırmada doğru yol ne olurdu? UNION veya döngü olmadan tek bir SELECT ifadesi ile yapmak mümkün mü? Herhangi bir katılımcı var mı? Şimdiden teşekkürler. Girdi XML:İç içe XML'yi SQL tabloya ayrıştırma

<ObjectData> 
    <Parameter1>some value</Parameter1> 
    <Parameter2>other value</Parameter2> 
    <Dates> 
    <dateTime>2011-02-01T00:00:00</dateTime> 
    <dateTime>2011-03-01T00:00:00</dateTime> 
    <dateTime>2011-04-01T00:00:00</dateTime> 
    </Dates> 
    <Values> 
    <double>0.019974</double> 
    <double>0.005395</double> 
    <double>0.004854</double> 
    </Values> 
    <Description> 
    <string>this is row 1</string> 
    <string>this is row 2</string> 
    <string>this is row 3</string> 
    </Values> 
</ObjectData> 

İstenilen tablo çıktı: Ben OPENXML veya xml.nodes() işlevini kullanarak bir SEÇ SQL deyiminde sonra ben

Parameter1 Parameter2  Dates    Values  Description 

Some value Other value 2011-02-01 00:00:00.0 0.019974 this is row 1 
Some value Other value 2011-03-01 00:00:00.0 0.005395 this is row 2 
Some value Other value 2011-04-01 00:00:00.0 0.004854 this is row 3 

. Örneğin, aşağıdaki SELECT ifadesi, Değerler ve Tarihler (yani Değerlerin ve Tarihlerin tüm permütasyonları) arasındaki üretimle sonuçlanır; bu, kaçınmak istediğim bir şeydir. XML ayrıştırmak istiyorsa

SELECT 
doc.col.value('Parameter1[1]', 'varchar(20)') Parameter1, 
doc.col.value('Parameter2[1]', 'varchar(20)') Parameter2, 
doc1.col.value('.', 'datetime') Dates , 
doc2.col.value('.', 'float') [Values] 
FROM 
@xml.nodes('/ObjectData') doc(col), 
@xml.nodes('/ObjectData/Dates/dateTime') doc1(col), 
@xml.nodes('/ObjectData/Values/double') doc2(col); 

cevap

7

Alt öğelerden birinci, ikinci, üçüncü vb. Satırları seçmek için numara tablosundan yararlanabilirsiniz. Bu sorguda, sağlanan tarihler varsa, sayılara döndürülen satırları sınırlandırdım. Tarihlerden daha fazla değer veya açıklama varsa, bunu hesaba katmak için birleştirmeyi değiştirmeniz gerekir.

declare @XML xml = ' 
<ObjectData> 
    <Parameter1>some value</Parameter1> 
    <Parameter2>other value</Parameter2> 
    <Dates> 
    <dateTime>2011-02-01T00:00:00</dateTime> 
    <dateTime>2011-03-01T00:00:00</dateTime> 
    <dateTime>2011-04-01T00:00:00</dateTime> 
    </Dates> 
    <Values> 
    <double>0.019974</double> 
    <double>0.005395</double> 
    <double>0.004854</double> 
    </Values> 
    <Description> 
    <string>this is row 1</string> 
    <string>this is row 2</string> 
    <string>this is row 3</string> 
    </Description> 
</ObjectData>' 

;with Numbers as 
(
    select number 
    from master..spt_values 
    where type = 'P' 
) 
select T.N.value('Parameter1[1]', 'varchar(50)') as Parameter1, 
     T.N.value('Parameter2[1]', 'varchar(50)') as Parameter2, 
     T.N.value('(Dates/dateTime[position()=sql:column("N.Number")])[1]', 'datetime') as Dates, 
     T.N.value('(Values/double[position()=sql:column("N.Number")])[1]', 'float') as [Values], 
     T.N.value('(Description/string[position()=sql:column("N.Number")])[1]', 'varchar(max)') as [Description] 
from @XML.nodes('/ObjectData') as T(N) 
    cross join Numbers as N 
where N.number between 1 and (T.N.value('count(Dates/dateTime)', 'int')) 
+0

Çok teşekkür ederim Mikael. Gerçekten iyi çalışıyor! Sözdizimi hala akıl almaz, biraz daha basit olmasını hayal ettim ... :) – Puzzled

-1

Genellikle, bunu Perl, Python, Java veya a) bir XML DOM sahip olduğunu C# ve b) ilişkisel veritabanı ile iletişim kurabilir gibi bir programlama dili yapardım.

Burada C# size okuma ve yazma XML ilgili bazı temel unsurları gösteren kısa bir yazı ... ve hatta bir SQL sorgusu bir XML belgesi oluşturmak için nasıl bir örnek vardır (bir çizgide!):

http://www.c-sharpcorner.com/uploadfile/mahesh/readwritexmltutmellli2111282005041517am/readwritexmltutmellli21.aspx

+0

Teşekkür ederim, ama bu aradığım şey değil. OPENXML veya xml.nodes() işlevselliğini kullanan bir SQL ifadesinden sonra yaşıyorum. Aşağıdaki select deyimi, kaçınmak istediğim bir şey olan Değerler ve Tarihler arasında üretimle sonuçlanır. SELECT doc.col.value ('Parametre1 [1]', 'varchar (20)') Parametre1, doc.col.value ('Parametre2 [1]', 'varchar (20)') Parametre2, doc1 .col.value ('.', 'datetime') Tarihler , doc2.col.value ('. [1]', 'float') [Değerler] FROM @ xml.nodes ('/ ObjectData') doc (col) , @ xml.nodes ('/ ObjectData/Tarihler/dateTime') doc1 (sütun) , @ xml.nodes ('/ ObjectData/Değerler/çift') doc2 (sütun); – Puzzled

2

OPENXML işlevini kullanın.

INSERT INTO table SELECT * FROM OPENXML(source, rowpattern, flags) 

netlik için dokümantasyon bağlantısını ilk örneğe bakın lütfen: Bu bir satır kümesi sağlayıcı (Bu XML çözümlenen satır kümesi döndürür) ve dolayısıyla SELECT kullanılan ya da benzeri INSERT edilebilir olduğunu.