Kalian sangat membantu terakhir kali dan saya menjadi lebih nyaman dengan XML di SQL Server tetapi masih sangat pemula.

Tantangan terbaru saya adalah saya memiliki node yang bernama sama, seperti hingga 50 kali dan hanya nomor yang membedakannya:

<QuoteHeaderXML>
  <QuoteHeaderData>
    <QuoteHeader>
      <Configurable01 Value="" Name="Credit Memo" />
      <Configurable02 Value="" Name="Contact Person" />
      <Configurable04 Value="N/A" Name="Fed Ex Rated" />
      <Configurable05 Value="Not Branded" Name="Branding" />
      <Configurable06 Value="100%" Name="Project Status" />
      <Configurable07 Value="" Name="Project Name" />
      <Configurable08 Value="None" Name="Project Manager" />
      <Configurable09 Value="" Name="Shipping Notes" />
      <Configurable10 Value="False" Name="High Profile Order" />
      <Configurable11 Value="New Construction" Name="Project Type" />
      <Configurable12 Value="Single-family" Name="Channel" />
      <Configurable13 Value="US - Texas - Northern" Name="Job Location" />
      <Configurable20 Value="Dealer Warehouse" Name="Delivery Destination" />
    </QuoteHeader>
  </QuoteHeaderData>
</QuoteHeaderXML>

Jadi jika saya ingin menarik kolom untuk ConfigurableNN, Nama dan Nilai, saya harus menulis ini 50x untuk menarik semuanya ke dalam baris individual di mana mereka ada ... atau memanggil masing-masing untuk masing-masing 50 berakhir di 150+ tabel kolom! Saya tidak suka opsi ini.

Sebagai gantinya, saya ingin menulis kode untuk menarik ConfigurableNN, Name, dan Value sekali, tetapi memintanya secara dinamis mengubah jumlah node berdasarkan penghitung. Namun, saya tidak dapat melakukannya karena mengeluh "Argumen 1 dari metode "nilai" tipe data XML harus berupa string literal.".

Inilah yang saya coba dan samarkan dari posting yang saya temukan tetapi tidak dapat berfungsi ... ada saran atau ini tidak mungkin?

WHILE @ConfigCounter <= 50
    BEGIN
        SET @CfgNum = case when @ConfigCounter < 10 then '0' else '' end + cast(@ConfigCounter as varchar(2));

        select t.x.value('(Configurable'+cast(@CfgNum as varchar(2))+'/@Name)[1]','varchar(255)')   ConfigurableFieldName
              ,t.x.value('(Configurable'+cast(@CfgNum as varchar(2))+'/@Value)[1]','varchar(255)')  ConfigurableFieldValue
          from @XMLData.nodes('//QuoteHeaderXML/QuoteHeaderData/QuoteHeader') as T(X)
         where t.x.value('(Configurable'+cast(@CfgNum as varchar(2))+'/@Value)[1]','varchar(255)') is not null      

        SET @ConfigCounter = @ConfigCounter + 1; 
    END

Terima kasih sebelumnya atas bantuan, tip dan/atau ide! =)

2
AKenn 15 Desember 2017, 02:33

1 menjawab

Jawaban Terbaik

Jika XML ini berada di bawah kendali Anda, Anda harus mengubahnya. Ini adalah desain yang sangat buruk, untuk memisahkan elemen yang sama dengan nomor lari sebagai bagian dari nama elemen. Jika Anda membutuhkan nomor ini, Anda dapat menambahkannya sebagai atribut seperti

<Configurable Nr="01" Value="" Name="Credit Memo" />

Anda tidak memerlukannya, karena urutan elemen dalam am XML dijamin (bukan urutan atribut), tetapi Itu membuat beberapa kueri lebih mudah.

Jika Anda harus tetap dengan ini, Anda dapat menggunakan Asterisk * untuk mendapatkan semua node di bawah <QuoteHeader> sekaligus:

DECLARE @xml XML = 
N'<QuoteHeaderXML>
  <QuoteHeaderData>
    <QuoteHeader>
      <Configurable01 Value="" Name="Credit Memo" />
      <Configurable02 Value="" Name="Contact Person" />
      <Configurable04 Value="N/A" Name="Fed Ex Rated" />
      <Configurable05 Value="Not Branded" Name="Branding" />
      <Configurable06 Value="100%" Name="Project Status" />
      <Configurable07 Value="" Name="Project Name" />
      <Configurable08 Value="None" Name="Project Manager" />
      <Configurable09 Value="" Name="Shipping Notes" />
      <Configurable10 Value="False" Name="High Profile Order" />
      <Configurable11 Value="New Construction" Name="Project Type" />
      <Configurable12 Value="Single-family" Name="Channel" />
      <Configurable13 Value="US - Texas - Northern" Name="Job Location" />
      <Configurable20 Value="Dealer Warehouse" Name="Delivery Destination" />
    </QuoteHeader>
  </QuoteHeaderData>
</QuoteHeaderXML>';

SELECT ConfigurableX.value(N'local-name(.)',N'nvarchar(max)') AS NodeName
      ,ConfigurableX.value(N'@Value',N'nvarchar(max)') AS Value
      ,ConfigurableX.value(N'@Name',N'nvarchar(max)') AS Name
FROM @xml.nodes(N'/QuoteHeaderXML/QuoteHeaderData/QuoteHeader/*') AS GetAllBelowQuoteHeader(ConfigurableX);

Hasil

+----------------+-----------------------+----------------------+
| NodeName       | Value                 | Name                 |
+----------------+-----------------------+----------------------+
| Configurable01 |                       | Credit Memo          |
+----------------+-----------------------+----------------------+
| Configurable02 |                       | Contact Person       |
+----------------+-----------------------+----------------------+
| Configurable04 | N/A                   | Fed Ex Rated         |
+----------------+-----------------------+----------------------+
| Configurable05 | Not Branded           | Branding             |
+----------------+-----------------------+----------------------+
| Configurable06 | 100%                  | Project Status       |
+----------------+-----------------------+----------------------+
| Configurable07 |                       | Project Name         |
+----------------+-----------------------+----------------------+
| Configurable08 | None                  | Project Manager      |
+----------------+-----------------------+----------------------+
| Configurable09 |                       | Shipping Notes       |
+----------------+-----------------------+----------------------+
| Configurable10 | False                 | High Profile Order   |
+----------------+-----------------------+----------------------+
| Configurable11 | New Construction      | Project Type         |
+----------------+-----------------------+----------------------+
| Configurable12 | Single-family         | Channel              |
+----------------+-----------------------+----------------------+
| Configurable13 | US - Texas - Northern | Job Location         |
+----------------+-----------------------+----------------------+
| Configurable20 | Dealer Warehouse      | Delivery Destination |
+----------------+-----------------------+----------------------+
2
Shnugo 15 Desember 2017, 08:50