Import pliku .xml do SQL Server

0

Dzień dobry,

jestem na początku drogi z programowaniem SQL i natrafiłem na problem, z którym borykam się od dłuższego czasu.
Mam plik XML (poniżej jego treść), z którego chcę odczytać dane z użyciem SQL.
Testowo chciałbym odczytać np atrybut EORI z węzła "/IE529/Zwolnienie/Nadawca". Niestety co bym nie zrobił otrzymuje pustą wartość.
Czy może ktoś podpowiedzieć, co robię nie tak?

Dodam tylko że plik xml zmodyfikowałem ręcznie (dane) na potrzeby umieszczenia go w przestrzeni publicznej

Poniżej kod którym chcę odczytać dane z przesłanego pliku, a wynik mam "pusty":

DECLARE @xmldata XML

SELECT @xmldata=BulkColumn FROM OPENROWSET (BULK 'C:\test1.xml',SINGLE_BLOB) as T1

DECLARE @docHandle int
EXEC sp_xml_preparedocument @docHandle OUTPUT, @xmldata

SELECT * FROM OPENXML(@docHandle, '/IE529/Zwolnienie/Nadawca', 1)
WITH
(	
	EORI VARCHAR(20) 
)

EXEC sp_xml_removedocument @docHandle
GO

Inne przykłady znalezione w sieci mi działają, natomiast z tym konkretnym typem plików mam ogromny problem.
Będę wdzięczny za pomoc.

EDIT: Zawartość pliku XML, zgodnie z Waszą sugestią, aby nie trzeba było sciągać archiwum

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<IE529 xmlns="http://www.mf.gov.pl/xsd/ECS/IE529_v1-0.xsd" EmailPodmiotu="[email protected]" NrWlasny="22IETESTNR341" PlacowkaPodmiotu="00">
  <Zwolnienie CRN="CRN123" DataPrzyjecia="2022-12-29T15:38:30" DataZwolnienia="2022-12-29T15:39:06" Kontenery="0" KrajPrzeznaczenia="UK" KrajWysylki="PL" LiczbaOpakowan="1" LiczbaPozycji="1" MRN="123MRN345" MasaBrutto="1.000" NrWlasny="123Nrwlasny" OdprawaScentralizowana="0" P1a="EU" P1b="A" Tranzyt="0" UCWyprowadzenia="UC1234" UCWywozu="UW1234" drukEAD="0">
    <Nadawca EORI="PL123456789" KodPocztowy="12-200" Kraj="PL" Miejscowosc="Miejscowosc xyz" Nazwa="NazwaXYZ" Regon="12343REGON" TIN="PL123456789" UlicaNumer="ul. xyzq" />
    <Odbiorca KodPocztowy="03057" Kraj="UK" Miejscowosc="xyz" Nazwa="Nazwaxyz" UlicaNumer="UlicaXyz" />
    <ZglaszajacyPrzedstawiciel DataWpisu="" EORI="" EmailPodmiotu="" KodPocztowy="" Kraj="" Miejscowosc="" Nazwa="" NrWpisu="" Przedstawicielstwo="" Regon="" TIN="" UlicaNumer="" />
    <TransportWewnetrzny Rodzaj="" Znaki="" />
    <TransportNaGranicy Kraj="" Rodzaj="" Znaki="" />
    <Lokalizacja Miejsce="" />
    <WarunkiDostawy Kod="" Miejsce="" MiejsceKod="" />
    <Transakcja Kurs="" Rodzaj="" Waluta="" Wartosc="" />
    <Towar KodTaric="" KodTowarowy="" MasaNetto="" Nr="" OpisTowaru="" ProceduraPoprzednia="" ProceduraWnioskowana="">
      <Opakowanie LiczbaOpakowan="" Rodzaj="" Znaki="" />
      <DokumentPoprzedni Kod="" Nr="" />
      <DokumentWymagany Kod="" Nr="" PozId="" />
      <DokumentWymagany Kod="" Nr="" PozId="" />
      <DokumentWymagany Kod="" Nr="" PozId="" />
    </Towar>
  </Zwolnienie>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="id-123435"></ds:Signature>
</IE529>

0

Wrzuć kawałek tego XMLa tu - nikt normalny nie będzie osiągał jakiego przypadkowego archiwum z internetu.
Wiesz co jest w zmiennej @xmldata po selekcie?

No to pierwsze pytanie, czy ty używasz PL/SQL czy T-SQLa z MS Sql servera ?

Jesteś przekonany ze twój dokument jest poprawny w sensie składni XMLa?

Sprawdź co ci zwraca sp_xml_preparedocument

0

Dziękuję za odpowiedź i przepraszam za zamieszanie. Chodziło mi o T-SQL z MS SQL Server.

Do postu dodałem plik XML, który zamieściłem w załączniku.

Tak, dokument jest poprawny - jest generowany przez inne oprogramowanie powszechnie używane. Ponadto jest przetwarzany też przez inny soft i jest ok.

W zmiennej @xmlDATA po selekcie jest cały plik xml

<IE529 xmlns="http://www.mf.gov.pl/xsd/ECS/IE529_v1-0.xsd" EmailPodmiotu="[email protected]" NrWlasny="22IETESTNR341" PlacowkaPodmiotu="00"><Zwolnienie CRN="CRN123" DataPrzyjecia="2022-12-29T15:38:30" DataZwolnienia="2022-12-29T15:39:06" Kontenery="0" KrajPrzeznaczenia="UK" KrajWysylki="PL" LiczbaOpakowan="1" LiczbaPozycji="1" MRN="123MRN345" MasaBrutto="1.000" NrWlasny="123Nrwlasny" OdprawaScentralizowana="0" P1a="EU" P1b="A" Tranzyt="0" UCWyprowadzenia="UC1234" UCWywozu="UW1234" drukEAD="0"><Nadawca EORI="PL123456789" KodPocztowy="12-200" Kraj="PL" Miejscowosc="Miejscowosc xyz" Nazwa="NazwaXYZ" Regon="12343REGON" TIN="PL123456789" UlicaNumer="ul. xyzq" /><Odbiorca KodPocztowy="03057" Kraj="UK" Miejscowosc="xyz" Nazwa="Nazwaxyz" UlicaNumer="UlicaXyz" /><ZglaszajacyPrzedstawiciel DataWpisu="" EORI="" EmailPodmiotu="" KodPocztowy="" Kraj="" Miejscowosc="" Nazwa="" NrWpisu="" Przedstawicielstwo="" Regon="" TIN="" UlicaNumer="" /><TransportWewnetrzny Rodzaj="" Znaki="" /><TransportNaGranicy Kraj="" Rodzaj="" Znaki="" /><Lokalizacja Miejsce="" /><WarunkiDostawy Kod="" Miejsce="" MiejsceKod="" /><Transakcja Kurs="" Rodzaj="" Waluta="" Wartosc="" /><Towar KodTaric="" KodTowarowy="" MasaNetto="" Nr="" OpisTowaru="" ProceduraPoprzednia="" ProceduraWnioskowana=""><Opakowanie LiczbaOpakowan="" Rodzaj="" Znaki="" /><DokumentPoprzedni Kod="" Nr="" /><DokumentWymagany Kod="" Nr="" PozId="" /><DokumentWymagany Kod="" Nr="" PozId="" /><DokumentWymagany Kod="" Nr="" PozId="" /></Towar></Zwolnienie><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="id-123435" /></IE529>

W "uchwycie" zwracanym przez sp_xml_preparedocument jest wartość INT

Testowo jak wykonam dodatkowego takiego selecta:

SELECT 	*
FROM OPENXML(@docHandle, '/', 1)

To otrzymuje wynik jak poniżej (wartość teoretycznie jest, ale przypisana do # text a nie atrybutu EORI)
wynik select.png

0

To jest kwestia tego, jak pareser traktuje tagi i ich atrybuty i wartości. Poza tym, jak sięgasz do taga "/IE529/Zwolnienie/Nadawca" to on jest pusty a posiada atrybuty. Zobacz jak to wygląda w dokumentacji: https://learn.microsoft.com/en-us/sql/t-sql/functions/openxml-transact-sql?view=sql-server-ver16

W "uchwycie" zwracanym przez sp_xml_preparedocument jest wartość INT

Nie chodzi o typ, tylko konkretną wartość.

0
S4t napisał(a):

To jest kwestia tego, jak pareser traktuje tagi i ich atrybuty i wartości. Poza tym, jak sięgasz do taga "/IE529/Zwolnienie/Nadawca" to on jest pusty a posiada atrybuty. Zobacz jak to wygląda w dokumentacji: https://learn.microsoft.com/en-us/sql/t-sql/functions/openxml-transact-sql?view=sql-server-ver16

W "uchwycie" zwracanym przez sp_xml_preparedocument jest wartość INT

Nie chodzi o typ, tylko konkretną wartość.

Wartość zmienia się z każdym wywołaniem: 127, w kolejnym 129 itd.

Dokumentacje przeglądałem. W związku z tym, że są to atrybuty to ustawiam flagę w OPENXML na "1", ale mimo tego nie odczytuje danych, dlatego pozwoliłem sobie tutaj zapytać

1

Generalnie nie potrzebujesz openxml, skoro używasz typu xml.
Musisz też zwrócić uwagę, że procesowany xml ma zdefiniowaną domyślną przestrzeń nazw i to w niej musisz szukać używając xpath:

DECLARE @xmldata XML
SET @xmldata = (select * FROM OPENROWSET (BULK 'C:\test1.xml',SINGLE_CLOB) as T1)

;WITH XMLNAMESPACES(DEFAULT 'http://www.mf.gov.pl/xsd/ECS/IE529_v1-0.xsd')
select
p.value('@EORI','varchar(20)') EORI
FROM @xmldata.nodes('/IE529/Zwolnienie/Nadawca') AS A(p)
1

To w bonusie wersja z openxml:

DECLARE @xmldata XML

SELECT @xmldata=BulkColumn FROM OPENROWSET (BULK 'C:\test1.xml',SINGLE_BLOB) as T1

DECLARE @docHandle int
EXEC sp_xml_preparedocument @docHandle OUTPUT, @xmldata, N'<root xmlns:d="http://www.mf.gov.pl/xsd/ECS/IE529_v1-0.xsd"/>'

SELECT * FROM OPENXML(@docHandle, '/d:IE529/d:Zwolnienie/d:Nadawca', 2)
WITH
(	
	EORI VARCHAR(20) '@EORI'
)

EXEC sp_xml_removedocument @docHandle
GO
0
Panczo napisał(a):

To w bonusie wersja z openxml:

Bardzo dziękuję za pomoc. Rzeczywiście muszę poczytać o przestrzeni nazw - dziękuje za zwrócenie na to uwagi.
Dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1