Laden...

XML Inhalte aus SQL Server auslesen

Erstellt von Anna85 vor 5 Jahren Letzter Beitrag vor 4 Jahren 6.206 Views
Thema geschlossen
A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren
XML Inhalte aus SQL Server auslesen

Hallo zusammen,
ich habe eine Aufgabe, die Datein aus XML in eine Tabelle einzulesen.
die XML Datei habe ich schon zu SQL Server Management imortiert. Jetzt muss ich die DAten auselsen, aber leider passiert nicht viel.

Die XML Datei im grob sieht so aus:


<record type="Authority">
    <leader>00000nz  a2200000nc 4500</leader>
    <controlfield tag="001">1011387409</controlfield>
    <controlfield tag="003">DE-101</controlfield>
    <controlfield tag="005">20150227101359.0</controlfield>
    <controlfield tag="008">110430n</controlfield>
    <datafield tag="024" ind1="7" ind2=" ">
      <subfield code="a">http://d-nb.info/brd/123</subfield>
      <subfield code="2">uri</subfield>
    </datafield>
    <datafield tag="035" ind1=" " ind2=" ">
      <subfield code="a">(DE-101)105f563</subfield>
    </datafield>
    <datafield tag="035" ind1=" " ind2=" ">
      <subfield code="a">(DE-588)632a452</subfield>
    </datafield>
  </record>

bis jetzt habe ich so was gemacht:


SELECT
 
 orga.ref.value('leader[1]','varchar(255)') leader,
 orga.ref.value('controlfield[1]','varchar(255)') controlfield,
 orga.ref.value('datafield[1]','varchar(255)') datafield,
 orga.ref.value('subfield[1]','varchar(255)') subfield
 
 
FROM (
--Abfrage auf Import-Tabelle
 Select Top 1 xmlData 
 FROM dbo.orgaImportHistory
 order by loadedDateTime desc
) xml 
 
outer apply xml.xmlData.nodes('collection/record/datafield') orga(ref)

Allerdings als Ergebnis bekomme ich in Zeilen NULL. Und ich möchte die Daten aus XML holen.

Könnte mir jemnad weiter helfen?

Falls ich im falschen Forum bin, bitte mitteilen!
Viele Grüße aus Ulm!

6.911 Beiträge seit 2009
vor 5 Jahren

Hallo Anna85,

kannst du noch zeige wie die Ziel-Tabelle aufgebaut ist (das Schema), sonst ist es schwer zu erkennen wie die Zuordnung sein soll.

die XML Datei habe ich schon zu SQL Server Management imortiert

Wie meinst du das?

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Hi,

mit Befehl:


select * from tab.org;

bekomme ich meine xml Datei, die sieht so aus, wie oben, wenn ich sie öffne.

Dann möchte ich bzw denke ich, es wäre so über: select, was ich oben geschrieben die Daten aus xml einzulesen. Es soll leader, controlfield, datafield, subfield als Ergebnis kommen.

Allerdings sind mehrere controlfields. Ich möchte dann auch natürlich so abfragen, dass in der Tabelle nur controllfield gezeigt werden, wo der tag = "001". und subfield wo code ="a" und datafield tag ="035". etc.

mit der--Abfrage auf Import-Tabelle bekomme ich die gewünschte xml und aus diesem xml möchte ich die Parametr ablesen, wie schon oben beschrieben.

Ich bin leider kein Programmierer/Informatiker. Deshalb bitte ich ganz toll um die Hilfe.

Viele Grüße

6.911 Beiträge seit 2009
vor 5 Jahren

Hallo Anna85,

mir ist noch nichts klarer geworden 😉

Führ folgendes SQL aus (ersetze das XXX durch den Namen der Ziel-Tabelle):


declare @tableName nvarchar(100) = 'XXX'

select  schema_name(t.schema_id) SchemaName,
        t.name TableName,
        c.column_id ColId,
        c.name ColName,
        t.name DataType,
        c.max_length MaxLength,
        c.precision Precision
from    sys.tables t
join    sys.columns c
    on  t.object_id = c.object_id
left join sys.types typ
    on  c.user_type_id = typ.user_type_id
where   t.name = @tableName
order by SchemaName, TableName, ColId

Und poste das Ergebnis hier (im Ergebnis-Reiter klicken -> Strg + A -> Strg + Umsschalt + C fürs Kopieren).

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

16.834 Beiträge seit 2008
vor 5 Jahren

Gü, ich vermute, dass Anna85 hier eine Xml-Column (quasi Hybrid NoSQL, xml Data Type) hat und nun über T-SQL Features auf die strukturellen Informationen der Xml-Value zugreifen will.

Jedenfalls verstehe ich das so.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Hallo,

Verzeihung, was verstehst du nicht?

ich habe eine xml Datei in SQL Server eingelesen. Wenn ich

Select Top 1 xmlData
FROM dbo.orgaImportHistory
order by loadedDateTime desc 

mache bekomme ich xml Datei, als Ergebnis, die ich anklicke und sehe ich die Struktur der Datei.

Jetzt möchte ich aus dieser Datei die Parameter auslesen, die ich in letzten Beitrag geschrieben habe.

Wenn ich dein Code einlese, als Ergebnis bekomme ich die Spalten, die du definiert hast, also: SchemaName,, TableNAme, CoId usw. aber leer, also keine Zeilen wurden betroffen.
Das ist leider das gleiche Ergebnis, wie mit meinem Code:

SELECT

orga.ref.value('leader[1]','varchar(255)') leader,
orga.ref.value('controlfield[1]','varchar(255)') controlfield,
orga.ref.value('datafield[1]','varchar(255)') datafield,
orga.ref.value('subfield[1]','varchar(255)') subfield


FROM (
--Abfrage auf Import-Tabelle
Select Top 1 xmlData
FROM dbo.orgaImportHistory
order by loadedDateTime desc
) xml

outer apply xml.xmlData.nodes('collection/record/datafield') orga(ref)

Und ich weiß nicht, wie kann ich dem Programm sagen soll: hol die Daten 😦

Falls du noch fragen hast, sag bitte bescheid, ich versuche so formulieren, dass du es verstehst.

16.834 Beiträge seit 2008
vor 5 Jahren

Naja, leider müssen wir komplett raten wie und als was Du die XML importiert hast.
Mit dem Output des Snippets von Gü würden wir verstehen, wie Deine Datenbank überhaupt aufgebaut ist - so müssen wir komplett raten anhand der SQL Befehle; wissen aber gar nicht, ob diese richtig sind.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Ok, die .xml Datei hat andere Mitarbeiter importiert, wie? ich weiss es leider nicht, er ist nicht da und kommt demnächst nicht.

Ich arbeite auf MSSQl Sever Management Studio, wo alle Tabellen sind.
Wenn ich die Tabelle dbo.orgaImportHistory abfrage mit select * from tabelle, bekomme ich als Ergebnis die xml Datei, die ich anklicken kann und sehe ich der Aufbau der xml (s. oben)

Mein Job ist die Felder, die ich geschrieben habe in eine Tabelle zu packen, damit das so aussieht:


leader  |    controlfield   |  datafield  | subfield


Deshalb habe ich der Select aufgebaut:


SELECT

orga.ref.value('leader[1]','varchar(255)') leader,
orga.ref.value('controlfield[1]','varchar(255)') controlfield,
orga.ref.value('datafield[1]','varchar(255)') datafield,
orga.ref.value('subfield[1]','varchar(255)') subfield


FROM (
--Abfrage auf Import-Tabelle
Select Top 1 xmlData
FROM dbo.orgaImportHistory
order by loadedDateTime desc
) xml

outer apply xml.xmlData.nodes('collection/record/datafield') orga(ref)

aber bekomme ich als Ergebnios Spalten mit Namen: leader, controlfield....., aber leer.

Entschuldigung, habe ich besser beschrieben, oder bewegen ich mich im Kreis?

656 Beiträge seit 2008
vor 5 Jahren

Ich rat jetzt einfach mal ins blaue, aber versuch mal beim X-Path hinten das /datafield wegzulassen:

SELECT
...
outer apply xml.xmlData.nodes('collection/record') orga(ref)

Mit .value(...) greifst du nämlich auf das Element zu, was letztendlich aus dem apply rauskommt; und rein namenstechnisch sind die Elemente im <record> zu finden, nicht im <datafield>

4.939 Beiträge seit 2008
vor 5 Jahren

Du hast ja (in der letzten Zeile) explizit auf 'datafield' verwiesen. Laß das mal weg:


outer apply xml.xmlData.nodes('collection/record') orga(ref)

(bzw. nur 'record', falls es keine collection als äußere XML-Node gibt)

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Hi Th69, BhaaL,

danke, aber leider habe ich das gleiche Ergebnis, wie bei mir:
Wenn ich mit:

outer apply xml.xmlData.nodes('record') orga(ref)

mache, bekomme ich die Spaltennamen als Ergebniss und NULL in der Zeilen. (in meldung steht: 1 Zeile getroffen)

Wenn ich mit:

cross apply xml.xmlData.nodes('record') orga(ref)

mache, erhalte ich leere Spaltennamen als Ergebniss. (in Meldung steht: 0 Zeilen getroffen)

Mir fehlt jetzt an, spielt das noch eine Rolle??? in dem XML oben steht das:

<collection xmlns="http://www.loc.gov/MARC21/slim">

Kann sein, dass es namespace-Problem ist???

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Guten Morgen,
könnte mir jemand hier weiter helfen?

Viele Grüße
Anna

656 Beiträge seit 2008
vor 5 Jahren

Ja, das ist ein Namespace Problem (was am gekürzten Snippet leider nicht ersichtlich war).
Sobald du Namespaces benutzt, ist das wie in anderen (Programmier-)Sprachen; du meinst etwas anderes wenn der Namespace anders ist.

Da du einen default Namespace hast, gilt der automatisch für alle Elemente; sofern nicht ein anderer Namespace (über das xmlns Attribut, oder ein Präfix was vorher per xmlns:yourPrefixHere definiert wurde) näher dran angegeben wird.

Vermutlich bräuchtest du sowas:

SELECT

orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:leader[1]','varchar(255)') leader,
orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield,
...
outer apply xml.xmlData.nodes('collection/record') orga(ref)

Der Namespace muss leider in jedes .value rein, weils unabhängige Ausdrücke sind. Dabei ist jedoch egal, wie du den Namespace nennst; solang du ihn später vor das Element schreibst.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Guten Morgen,

leider es funktioniert nicht.
Wenn ich mit outer apply mache, bekomme ich eine Zeile mit NULL.
Wenn ich mit cross apply machen, bekomme ich eine leere Zeile.

Ich habe leider keine Ahnung, an was das liegen kann.

Die XML Datei sieht so aus:

<collection xmlns="http://www.loc.gov/MARC21/slim">
   <record type="Authority">
       <leader>00000nz  a2200000nc 4500</leader>
       <controlfield tag="001">1011387409</controlfield>
       <controlfield tag="003">DE-101</controlfield>
       <controlfield tag="005">20150227101359.0</controlfield>
       <controlfield tag="008">110430n</controlfield>
       <datafield tag="024" ind1="7" ind2=" ">
         <subfield code="a">http://d-nb.info/brd/123</subfield>
         <subfield code="2">uri</subfield>
       </datafield>
       <datafield tag="035" ind1=" " ind2=" ">
         <subfield code="a">(DE-101)105f563</subfield>
       </datafield>
       <datafield tag="035" ind1=" " ind2=" ">
          <subfield code="a">(DE-588)632a452</subfield>
       </datafield>
    </record>
</collection>

und ich habe deinen code angepasst:

SELECT

orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:leader[1]','varchar(255)') leader,
orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield


FROM (
--Abfrage auf Import-Tabelle
Select Top 1 xmlData
FROM dbo.orgaImportHistory
order by loadedDateTime desc
) xml

outer apply xml.xmlData.nodes('/') orga(ref)

656 Beiträge seit 2008
vor 5 Jahren

Ein wenig Selbstständigkeit wäre sicher nicht verkehrt; nachdem dein Dokument Namespaces benutzt gilt das natürlich auch hinten für dein outer apply.
Vermutlich wirst du mit dem Ergebnis aber nicht glücklich sein, da wäre ein X-Path Tutorial zu empfehlen.

4.939 Beiträge seit 2008
vor 5 Jahren

Kannst du denn nicht mal einen XML-Testeintrag erstellen ohne Namespace und schauen, ob du diesen dann auslesen kannst?
Und wenn dann der Zugriff paßt, dann die Umstellung auf den Namespace machen.

PS: Irritierend an deinen ersten Beiträgen war für mich zumindestens, daß du den Code explizit als C# getaggt hast (anstatt nur 'Code' zu verwenden bzw. dazuzuschreiben, daß es sich um (T-)SQL handelt).

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Kannst du denn nicht mal einen XML-Testeintrag erstellen ohne Namespace und schauen, ob du diesen dann auslesen kannst?
Und wenn dann der Zugriff paßt, dann die Umstellung auf den Namespace machen.

PS: Irritierend an deinen ersten Beiträgen war für mich zumindestens, daß du den Code explizit als C# getaggt hast (anstatt nur 'Code' zu verwenden bzw. dazuzuschreiben, daß es sich um (T-)SQL handelt).

c# habe ich verwendet, da ich das mit CODE nicht gesehen habe in der erste Stunde , wo ich hier was gepostet habe. Das war nicht mit Absicht.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Kannst du denn nicht mal einen XML-Testeintrag erstellen ohne Namespace und schauen, ob du diesen dann auslesen kannst?
Und wenn dann der Zugriff paßt, dann die Umstellung auf den Namespace machen.

Ich kann kaum programmieren, ich weiss leider nicht, wie ich XML-testeintrag machen könnte. Das ist das traurige an der Geschichte.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Ein wenig Selbstständigkeit wäre sicher nicht verkehrt; nachdem dein Dokument Namespaces benutzt gilt das natürlich auch hinten für dein outer apply.
Vermutlich wirst du mit dem Ergebnis aber nicht glücklich sein, da wäre ein
>
zu empfehlen.

Natürlich hast du volkomm recht, wenn ich mehr Ahnung hätte.
Ich versuche mein Bestes, mindestens denke ich so.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Ein wenig Selbstständigkeit wäre sicher nicht verkehrt; nachdem dein Dokument Namespaces benutzt gilt das natürlich auch hinten für dein outer apply.
Vermutlich wirst du mit dem Ergebnis aber nicht glücklich sein, da wäre ein
>
zu empfehlen.

ich habe bei cross apply auch namenspace eingebaut:

cross apply xmlData.nodes('declare namespace  marc21 = "http://www.loc.gov/MARC21/slim";  marc21:collection/ marc21:record/ marc21:datafield') 

aber bekomme ich Fehlermeldung:

Ungültiger Objektname 'xml.xmlData.nodes'.

Aber die Objektname ist richtig aus meiner seits, natürlich.

Kannst du mal schauen?

656 Beiträge seit 2008
vor 5 Jahren

An sich ist das Forum kein Code-Generator, aber ich will dich irgendwie auch nicht hängen lassen...
Bei mir klappt folgendes:

declare @xml table(xmlData xml not null);
insert into @xml values ('<collection xmlns="http://www.loc.gov/MARC21/slim">
   <record type="Authority">
       <leader>00000nz  a2200000nc 4500</leader>
       <controlfield tag="001">1011387409</controlfield>
       <controlfield tag="003">DE-101</controlfield>
       <controlfield tag="005">20150227101359.0</controlfield>
       <controlfield tag="008">110430n</controlfield>
       <datafield tag="024" ind1="7" ind2=" ">
         <subfield code="a">http://d-nb.info/brd/123</subfield>
         <subfield code="2">uri</subfield>
       </datafield>
       <datafield tag="035" ind1=" " ind2=" ">
         <subfield code="a">(DE-101)105f563</subfield>
       </datafield>
       <datafield tag="035" ind1=" " ind2=" ">
          <subfield code="a">(DE-588)632a452</subfield>
       </datafield>
    </record>
</collection>')



select
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:leader[1]','varchar(255)') leader,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/@tag','varchar(255)') datafield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/marc21:subfield[1]','varchar(255)') subfield
from @xml xml
outer apply xml.xmlData.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:collection/marc21:record') orga(ref)

Liefert mir als Ergebnis

leader                      controlfield     datafield     subfield
00000nz  a2200000nc 4500    1011387409       024           http://d-nb.info/brd/123

Hätte mein Beispiel mehrere record Elemente, würden auch mehrere Zeilen rauskommen (das macht der outer apply)

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Hi,

es funktioniert. Tausend Dank.
Ich hatte nur immer wieder probiert mit namenspace und select ohne insert.

Nun, wenn ich eine lange xml habe, kann ich so was nicht machen

Allerdings wenn ich das ausführe:


SELECT

orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:record[1]','varchar(255)') record,
orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield


FROM (
--Abfrage auf Import-Tabelle
Select Top 1 xmlData
FROM dbo.orgaImportHistory
order by loadedDateTime desc
) xml

--cross apply xml.xmlData.nodes('record') orga(ref)
cross apply xml.xmlData.nodes('declare namespace  marc21 = "http://www.loc.gov/MARC21/slim";  marc21:collection/ marc21:record/ marc21:datafield') orga(ref)

es funktioniert, aber zeigt nur 25 Nullen in 2 abgefragten Spalten.

656 Beiträge seit 2008
vor 5 Jahren

Das Insert brauch ich zum Testen, das brauchst du natürlich nicht. Bei dir muss stattdessen deine Unterabfrage rein, die das XML liefert.

Und irgendwie wundert mich nicht, dass du immer noch NULLs rausbekommst, wenn du im apply auf datafield gehst.
Erst kommt das apply - alles was dort rauskommt, wird ins orga.ref geschrieben; und ausgehend davon kannst du im Select mit .value auf Werte dieses Elements zugreifen.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Das Insert brauch ich zum Testen, das brauchst du natürlich nicht. Bei dir muss stattdessen deine Unterabfrage rein, die das XML liefert.

was meinst du mit Unterabfrage?
ich habe hier das eingebaut:

declare @xml table(xmlData xml not null);

Select Top 1 xmlData
FROM dbo.orgaImportHistory
order by loadedDateTime desc
select
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:leader[1]','varchar(255)') leader,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/@tag','varchar(255)') datafield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/marc21:subfield[1]','varchar(255)') subfield
from @xml xml
cross apply xml.xmlData.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:collection/marc21:record') orga(ref)

aber als Ergebnis habe ich xml datei bekommen und die 4 angefragte Felder (leer)

Ich stelle mich mehr als doof vor.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

HAllo, kann man bei XML Auslesen auch die Bedingunen in SQl formulieren?
Ich habe hier:

eclare @xml table(xmlData xml not null);
insert into @xml values ('<collection xmlns="http://www.loc.gov/MARC21/slim">
   <record type="Authority">
       <leader>00000nz  a2200000nc 4500</leader>
       <controlfield tag="001">1011387409</controlfield>
       <controlfield tag="003">DE-101</controlfield>
       <controlfield tag="005">20150227101359.0</controlfield>
       <controlfield tag="008">110430n</controlfield>
       <datafield tag="024" ind1="7" ind2=" ">
         <subfield code="a">http://d-nb.info/brd/123</subfield>
         <subfield code="2">uri</subfield>
       </datafield>
       <datafield tag="035" ind1=" " ind2=" ">
         <subfield code="a">(DE-101)105f563</subfield>
       </datafield>
       <datafield tag="035" ind1=" " ind2=" ">
          <subfield code="a">(DE-588)632a452</subfield>
       </datafield>
    </record>
</collection>')



select
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:leader[1]','varchar(255)') leader,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/@tag','varchar(255)') datafield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/marc21:subfield[1]','varchar(255)') subfield
from @xml xml
outer apply xml.xmlData.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:collection/marc21:record') orga(ref)

versucht zu sagen:
from @xml xml where controlfield tag="005", aber erkennt das SQL den Feld nicht.
Kan mir jemand bitte einen Tip geben?

16.834 Beiträge seit 2008
vor 5 Jahren

Wenn ich nach suche Google-Suche nach sql server xml query condition erhalte zumindest ich Conditional Expressions (XQuery)
Vielleicht ist es das, was Du suchst.

IIRC wird die XML Funktionalität vom SQL Server halt kaum genutzt... daher vermute ich nicht, dass es all zu viele Leute gibt, die hier aktiv(er) helfen können als sich selbst die Doku durchzulesen und dann zu antworten.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Hallo, ich bin schon so weit gekommen, dass ich 1. gewünschte datafield bekomme, da es leicht ist,

aber ich möchte datafield = 035 noch auch ablesen, allerdings datafield =035 steht nicht immer auf 3. oder 4. Stelle, also ich kann nicht machen datafield[3].
Ich habe bei cross versucht dort eine Bedingung zu schreiben, aber es geht nicht.

Hat jemand eine Idee.

select
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:leader[1]','varchar(255)') leader,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/@tag','varchar(255)') datafield,
	--orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[2]/@tag','varchar(255)') datafield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/marc21:subfield[1]','varchar(255)') subfield
	

FROM (

--Abfrage auf Import-Tabelle

Select Top 1 xmlData

FROM dbo.orgaImportHistory

--order by loadedDateTime desc

) xml

--cross apply xml.xmlData.nodes('collection/record') orga(ref)
cross apply orga.ref.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; datafield[@tag="110"]') orga(ref)
cross apply xml.xmlData.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:collection/marc21:record') orga(ref)
656 Beiträge seit 2008
vor 5 Jahren

Dann schreibst du im X-Path einfach marc21:datafield[@tag = '035']

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Danke,
ich habe hier schon versucht:

cross apply xml.xmlData.nodes(marc21:datafield[@tag = "035"])

bekomm eich Fehler: Falsche Syntax in der Nähe von 'marc21:'.

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Hallo, ich habe es geschaft.
cross apply orga.ref.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[@tag="035"]') data035(ref)

Allerdings, habe ich z.B. datafield 035 zwei mal, und was ich schreibe liess mir das so ab, das ich zwei Zeilen habe:

leader                      controlfield     datafield     subfield
00000nz  a2200000nc 4500    1011387409       035        (DE-101)105f563
00000nz  a2200000nc 4500    1011387409       035         (DE-588)632a452

Was /Wie kann ich sagen, damit es nach komme ließ und damit es so aussieht:

leader                      controlfield     datafield     subfield
00000nz  a2200000nc 4500    1011387409       035        (DE-101)105f563, (DE-588)632a452


656 Beiträge seit 2008
vor 5 Jahren

Jedes cross apply multipliziert deine Zeilen. Das ist mit hoher Wahrscheinlichkeit nicht das, was du willst (also: mehrere cross apply). Schreibs doch einfach vorne beim orga.ref.value dazu, und nicht hinten?

Oder du belässt es so und benutzt STUFF (bzw. wenn du einen SQL Server 2017 oder neuer hast, STRING_AGG).

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 5 Jahren

Guten Morgen,

Vielen Dank BhaaL,
auf jeden Fall ist hier was falsch.
Nämlich die Abfrage zieht nur die Datensätze, wo das Feld 035 befüllt ist. Falls in Datensatz der Tag=035 nicht vorkommt, nimmt er ihm nicht mit, was auch falsch ist.
Ich brauche alle Datensätze, ob dort tag 035 da ist oder nicht.

Wie kann ich zusätzliche Formulierung noch dazu geben, wo steht, hol alle Datensätze, wenn tag35 nicht existiert schreib 0 in der Tabelle.

Viele Grüße!

A
Anna85 Themenstarter:in
59 Beiträge seit 2019
vor 4 Jahren

Guten Morgen,

ich habe weiter das Problem und komme ich nicht weiter. Ich habe es sio aufgebaut und das lies meine Zeile ab:


select
    orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:leader[1]','varchar(255)') leader,
    orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:controlfield[1]','varchar(255)') controlfield,
    orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/@tag','varchar(255)') datafield,
	orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[1]/marc21:subfield[1]','varchar(255)') subfield,
   orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[2]/@tag','varchar(255)') datafield,
   orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[2]/marc21:subfield[1]','varchar(255)') subfield,
   orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[3]/@tag','varchar(255)') datafield,
    orga.ref.value('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:datafield[3]/marc21:subfield[1]','varchar(255)') subfield,

	
FROM (

--Abfrage auf Import-Tabelle

Select Top 1 xmlData

FROM dbo.orgaImportHistory



--order by loadedDateTime desc

) xml


cross apply xml.xmlData.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:collection/marc21:record') as orga(ref)
--cross apply orga.ref.nodes('declare namespace marc21="http://www.loc.gov/MARC21/slim"; marc21:collection/marc21:record/datafield[@tag="110"]')


Nun wenn ein Datensatz mehr als 4 Datafields hat, sehe ich das nicht. Da die Datei sehr groß ist, möchte ich fragen: wie kann ich so auslesen, dass die Abfrage gib mir einfach zu jede controlfield alle datafileds. Es bedeutet 1 Datensatz wird 3 Datafields haben, ein andere 5 Datafileds.
Könnnte man das irgendwie vereinfachen?

Thema geschlossen