PDA

Pogčedajte punu verziju : [MSSQL] Eksport u xml, utf-8 encoding


nenana
09. 09. 2008., 20:10
Vec par sati pokusavam da razresim problem za koji se ipak nadam da je problem ipak u meni i da ja nešto uporno previdjam a ne u ogranicenju samog servera pa se nadam da ce mi neko tako nesto i potvrditi posto nemam vise ideje gde da potrazim resenje.

Naime, potrebno je da napravim procedure za eksport podataka iz MSSQL 2005 u nekoliko xml fajlova.
Za eksport podataka iz MSSQL-a obicno koristim naredbu bcp jer mi je tako najjednostavnije i sto ne zahteva nikakve dodatne alate osim onih koje imam u okviru samog mssql-a (tj. ceo kod strpam u jednu ili vise uskladistenih procedura, ubacim to u job koji se vrti onoliko puta dnevno koliko treba i to je to).
No, problem se pojavio na potpuno neocekivanom mestu a to je sto se trazi da generisani xml fajlovi imaju utf-8 encoding a mssql izgleda podrzava samo utf-16 i nema sanse da ga nateram da fajl eksportuje u utf-8 formatu!

Da li i gde ja to gresim kada ne mogu da pronadjem resenje za taj problem (a vec satima iscitavam sve zivo na tu temu po netu i svim mogucim helpovima u vezi mssql-a i utf-8) ili mssql stvarno nema podrsku za eksport u fajl koji bi bio u utf-8 formatu?!

Ako to stvarno ne mogu da uradim samo koristeci sql, opcija mi je da eksportujem u utf-16 a da onda radim konverziju u utf-8 nekim posebnim alatom ali koji bi morao da moze da se poziva i koristi iz komandne linije. Na netu postoje programi koji rade takve konverzije ali nijedan nema opciju da tako nesto moze da se uradi samo pozivom iz komandne linije.
:lost:

filmil
09. 09. 2008., 20:24
eksportujem u utf-16 a da onda radim konverziju u utf-8 nekim posebnim alatom [...] ali nijedan nema opciju da tako nesto moze da se uradi samo pozivom iz komandne linije.
:lost:

Како бре нема?! A иконв (iconv) (http://www.gnu.org/software/libiconv/documentation/libiconv/iconv.1.html)?

ф

jablan
09. 09. 2008., 20:26
Možda će morati i sed (http://unixhelp.ed.ac.uk/CGI/man-cgi?sed), ne bi li izmenio zaglavlje XML fajla... ;)

nenana
09. 09. 2008., 21:01
Како бре нема?! A иконв (iconv) (http://www.gnu.org/software/libiconv/documentation/libiconv/iconv.1.html)?

ф

Hm, koliko vidim radi se o ne-windows alatu a meni treba nesto za windows platformu...

ah, nadjoh i dll za windows pa cak i programce ali izgleda kao da nista ne uradi jer se i dalje otvara kao utf-16...moguce je da ipak uradi konveziju ali ne menja zaglavlje kao sto je jablan naveo...

filmil
09. 09. 2008., 21:09
Hm, koliko vidim radi se o ne-windows alatu a meni treba nesto za windows platformu...

Може да се инсталира у оквиру сигвина (Cygwin) (http://www.cygwin.com/), то је вероватно најлакши начин за под виндовс.

Да се разумемо, иконв само и искључиво конвертује кодне распореде, ако ти треба још нешто, онда је то посебна тема. Али углавном, сигвин има вероватно све што ти треба за аутоматске измене текста.

ф

Dragi Tata
09. 09. 2008., 21:49
TECkit bi trebalo da bude ono što tražiš, ali proveri u uputstvu: http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=TECkitDownloads

degojs
09. 09. 2008., 21:52
@nenana: evo nešto za 5 minuta, ali imaj na umu da ja pojma baš nemam oko tog enkodiranja. Valjda će da se javi Dragi Tata, on to ima otprilike u malom prstu.

static void Main( string[] args )
{
string str = "";
using ( StreamReader rdr = File.OpenText( args[0] ) )
{
str = rdr.ReadToEnd();
}

byte[] b = Encoding.UTF8.GetBytes( str );

using ( StreamWriter o = new StreamWriter( args[1] ) )
{
o.Write( Encoding.UTF8.GetString( b ) );
}
}

A to bi onda pokretao sa:
xyz.exe inputfajl.txt outputfajl.txt

E sad, pošto je ovo .NET rešenje, ukoliko radiš sa novijim SQL serverom (2005 ili 2008), onda bi tu konverziju mogao da uradiš i u istom, pošto može da se koristi .NET za programiranje sproc.

Eto, za početak nije loše, pretpstavljam - mislim da taj kod gore može i kraće da se napiše, itd. Takođe obrati pažnju da to čita ceo fajl u jednom cugu, itd, da ne bude problema oko velikih fajlova (onda prepravi da čitaš liniju po liniju, itd).

//edit: aha, eto i Nemanje.. oh, well.

nenana
10. 09. 2008., 11:02
TECkit bi trebalo da bude ono što tražiš, ali proveri u uputstvu: http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=TECkitDownloads
Ovo deluje vrlo interesantno i primenjlivo, upravo iščitavam dokumentaciju pa ću odmah i da isprobam.
Hvala!


@nenana: evo nešto za 5 minuta, ali imaj na umu da ja pojma baš nemam oko tog enkodiranja. Valjda će da se javi Dragi Tata, on to ima otprilike u malom prstu.
...
E sad, pošto je ovo .NET rešenje, ukoliko radiš sa novijim SQL serverom (2005 ili 2008), onda bi tu konverziju mogao da uradiš i u istom, pošto može da se koristi .NET za programiranje sproc.

Ma ni ja se baš ne razumem u priču oko enkodiranja pa zbog toga uvek tražim rešenja koja su (skoro) gotova jer time izbegavam da nešto zeznem iz sopstvenog neznanja.
No, hvala na podsećanju za upotrebu .NET-a. Koristimo SQL 2005 ali sam u brzini potpuno smetnula sa uma da tu mogu da ga koristim! Vrlo verovatno ću na kraju tako i uraditi, sad bih da zbog vrlo bliskog deadline-a primenim nešto što radi odmah na iole zadovoljavajući način a posle ću da optimizujem.

Hvala svima na odgovorima!

nenana
10. 09. 2008., 15:02
Samo da se javim da je operacija uspela i da je pacijent preživeo. :)
Evo kratkog opisa šta je tačno bio problem i kako je razrešen, za slučaj da se neko nadje u sličnoj situaciji:

Problem:
Eksport podataka iz MSSQL u txt/xml korišćenjem naredbe bcp s tim da rezultujuci fajl ima utf-8 encoding.

Pokušaj rešavanja:
Očekivano je bilo da sledeća opcija odradi posao:
bcp "select * from nekaTabela" queryout "C:\temp\nekaTabela.xml" -w -S"nekiServer" -U"user" -P"password"

Opcija -w radi ono sto i pise u helpu: Performs the bulk copy operation using Unicode characters.
Ono sto nije preciznije navedeno u helpu je da se kao rezultat dobija fajl koji ima encoding: UTF-16 with little-endian byte order.
Ništa nije bilo navedeno po pitanju dobijanja fajla koji je u UTF-8 formatu.

U potrazi za rešenjem na netu na par foruma predloženo je da se u pozivu bcp komande koriste opcije -c -C65001 uz napomenu da se tako dobija fajl koji nema BOM (byte-order mark).
Meni ova opcija nije radila jer se stalno dobijala poruka da ne postoji kodna strana 65001.
Umesto 65001 probano je sa opcijom -c C"UTF-8" i to je u prvi mah delovalo da radi jer se ne javlja pomenuta greška i kreira se fajl koji je izgleda u UTF-8 formatu ali je problem nastao ukoliko eksportujem sadržaj koji sadrži naša slova (š, ć, ž...).
Za takav fajl UltraEdit nije prijavljivao problem ali ga ipak nije prepoznavao kao UTF-8 dok je XMLSpy prijavljivao da u dokumentu postoje karakteri koji ne bi trebalo da se prisutni u dokumentu koji je u utf-8 formatu. Moguće je da je to sve imalo veze sa onim što se ne kreira onaj BOM, ne znam, u svakom slučaju opcija nije radila to što mi je trebalo.

Na kraju, problem za sada razrešavam tako što se transformacija u UTF-8 radi posle kreiranja xml fajla i to uz pomoć TECkit toolkita koji je DragiTata predložio (još jednom hvala za link :)).

Rešenje:
Ceo eksport sada ide u dva koraka:

U MSSQL-u:
bcp "select * from nekaTabela" queryout "C:\temp\InputFileUTF16.xml" -w -S"nekiServer" -U"user" -P"password"

a zatim se iz komandne linije poziva txtconv.exe sa sledećim opcijama:

c:\temp\txtconv -if utf16le -of utf8 -i InputFileUTF16.xml -o OutputFileUTF8.xml

Rezultujuci fajl (OutputFileUTF8.xml) je u korektnom utf-8 formatu i sa kreiranim BOM. :)