• Nie Znaleziono Wyników

5 DataRow row = table.NewRow();

6 while ( r .Read() && r.LocalName != ”Column”)

7 {

V ´ypis 9: Naˇcten´ı XML sch´ematu

M ˚uˇzeme vidˇet pouze fragment z k ´odu naˇc´ıt´an´ı sch´ematu. Cel´a funkce je mnohem delˇs´ı.

XmlTextReader realizuje sv ˚uj dopˇredn ´y pˇr´ıstup metodou Read. Respektive se d´ıky t´eto metodˇe posouv´a od jednoho elementu k druh´emu. Pro vytvoˇren´ı v ´yˇse uveden´e tabulky vytvoˇr´ıme nov ´y pr´azdn ´y ˇr´adek tabulky a pot´e vloˇz´ıme vˇsechny hodnoty element ˚u, kter´e se nach´az´ı ohraniˇceny elementem s n´azvem Column. Tento element slouˇz´ı pro oddˇelen´ı jednotliv ´ych z´aznam ˚u. Je to podobn´a struktura XML dokumentu jako u pˇredchoz´ıch v ´ypis ˚u.

Jeˇstˇe zb ´yv´a naˇc´ıst sch´ema tabulky ze serveru. Samozˇrejmˇe druh´a tabulka bude m´ıt naprosto totoˇznou strukturu, co se sloupc ˚u t ´yˇce. V poˇctu a obsahu ˇr´adk ˚u uˇz se mohou liˇsit. Tabulku ze serveru z´ısk´ame jednoduch ´ym SQL dotazem. Pouˇzijeme syst´emov ´y ka-talog.

SELECT COLUMN_NAME,IS_NULLABLE,COLUMN_DEFAULT,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ’@tableName’;

Za @tableName dosad´ıme jako parametr n´azev tabulky, jej´ıˇz sch´ema chceme naˇc´ıst ze serveru.

4.2 Porovn ´an´ı sch ´emat ˚u

Nyn´ı m´ame vytvoˇren´e tabulky sch´emat a n´astroj uˇz m´a co porovnat. V t´eto kapitole se pod´ıv´ame bl´ıˇze na funkci, kter´a porovn´av´a obˇe tabulky se sch´ematem. Ta je j´adrem cel´e transformace. Nejprve se porovn´a poˇcet ˇr´adk ˚u v obou tabulk´ach. Tak se jednoduˇse zjist´ı zda sloupec ubyl nebo pˇribyl. V pˇr´ıpadˇe stejn´eho poˇctu ˇr´adk ˚u se zavol´a funkce pro ob-novu dan´e tabulky a transformace neprobˇehne.

4.2.1 Sloupec ubyl

M ˚uˇze nastat situace, ˇze sloupec oproti p ˚uvodn´ımu sch´ematu ubyl. To znamen´a, ˇze v tabulce naˇcten´e z XML dokumentu je o ˇr´adek v´ıce neˇz v tabulce naˇcten´e ze serveru. V tom pˇr´ıpadˇe se vytvoˇr´ı dalˇs´ı tabulka, kter´a bude obsahovat rozd´ıln´e ˇr´adky, kter´e jsou v jedn´e tabulce a z´arove ˇn nejsou v tabulce naˇcten´e ze serveru. N´aslednˇe se z t´eto tabulky naˇctou pouze n´azvy sloupc ˚u do pˇredem pˇripraven´e glob´aln´ı generick´e kolekce. Pot´e je zavol´ana funkce pro obnovu dat. Pˇri obnovˇe se budou ignorovat vˇsechny n´azvy sloupc ˚u, kter´e jsou obsaˇzeny v generick´e kolekci.

1 var diff = xmlTable.AsEnumerable().Where(r => !sqlTable.AsEnumerable().Select(x => x[”

COLUMN NAME”]).ToList().Contains(r[”COLUMN NAME”])).ToList();

2 DataTable result = diff .CopyToDataTable();

V ´ypis 10: Vytvoˇren´ı tabulky

V ´ypis demonstruje vytvoˇren´ı tabulky s n´azvem result s rozd´ıln ´ymi ˇr´adky ze dvou p ˚uvodn´ıch tabulek. Jak uˇz n´azev vypov´ıd´a, XmlTable je tabulka naˇc´ıt´ana z XML souboru a SqlTable je tabulka naˇc´ıt´ana ze serveru. Jin ´ymi slovy tento k ´od vybere vˇsechny ˇr´adky z Xml-Table, kter´e nejsou obsaˇzen´e v tabulce SqlTable. Struktura tabulky bude opˇet stejn´a jako v pˇredeˇsl´em pˇr´ıpadˇe u naˇc´ıt´an´ı sch´emat. Pouˇzijeme promˇennou typu var, do kter´e nahra-jeme potˇrebn´e z´aznamy. A pot´e pˇres funkci CopyToDataTable nahranahra-jeme data do tabulky result.

4.2.2 Sloupec pˇribyl

Logicky m ˚uˇze tak´e nastat situace, ˇze sloupec oproti p ˚uvodn´ımu sch´ematu pˇribyl. V tomto pˇr´ıpadˇe opˇet vytvoˇr´ıme velice podobn ´ym zp ˚usobem tabulku s n´azvem result jako v si-tuaci s ubyt´ım sloupce.

1 var diff = sqlTable.AsEnumerable().Where(r => !xmlTable.AsEnumerable().Select(x => x[”

COLUMN NAME”]).ToList().Contains(r[”COLUMN NAME”])).ToList();

2 DataTable result = diff .CopyToDataTable();

V ´ypis 11: Vytvoˇren´ı tabulky

M ˚uˇzeme vidˇet, ˇze k ´od je na prvn´ı pohled prakticky totoˇzn ´y v pˇredeˇsl ´ym. Pˇri bliˇzˇs´ım po-hledu si lze vˇsimnout z´amˇeny XmlTable za SqlTable. Tento k ´od vybere ˇr´adky z SqlTable, kter´e se neshoduj´ı s ˇr´adky v XmlTable. Takto zaj´ıst´ıme, ˇze dan´a tabulka bude obsahovat pouze sloupce, kter´e pˇribyly oproti p ˚uvodn´ımu sch´ematu.

Ovˇsem v t´eto f´azi mus´ı n´astroj jednotliv´e ˇr´adky tabulky result zanalyzovat detailnˇeji.

Pro tento pˇr´ıpad n´astroj pouˇz´ıv´a dalˇs´ı funkci, kter´a ˇreˇs´ı pr´avˇe tuto problematiku. Proch´az´ı jednotliv´e ˇr´adky t´eto tabulky a u kaˇzd´eho z nich vyhodnocuje zda podporuje ˇci nepod-poruje NULL hodnoty. Tento fakt je kl´ıˇcov ´y pro cel ´y proces transformace.

Pokud sloupec podporuje NULL hodnoty, tedy hodnota sloupce IS NULLABLE v ˇr´adku je YES, nic se nedˇeje. V tom pˇr´ıpadˇe aplikace nemus´ı nic ˇreˇsit, protoˇze se na-stav´ı implicitn´ı hodnota sloupce jako NULL a nenastane ˇz´adn´a chyba. To byl pouze jeden

pˇr´ıklad. N´astroj m ˚uˇze pˇri pr ˚uchodu tabulkou result narazit na sloupec, kter ´y nepodpo-ruje NULL hodnoty. V tom pˇr´ıpadˇe se posuneme d´al a nyn´ı mus´ıme rozliˇsovat, zda m´a sloupec nastavenou v ´ychoz´ı hodnotu.

Jestliˇze sloupec m´a nastavenou v ´ychoz´ı hodnotu, n´astroj to opˇet nemus´ı ˇreˇsit jako v pˇredeˇsl´em pˇr´ıpadˇe. Pˇri obnovˇe se nastav´ı implicitn´ı hodnota a nenastane chyba. Ovˇsem n´as zaj´ım´a posledn´ı moˇznost, kdyˇz sloupec nem´a nastavenou v ´ychoz´ı hodnotu. Norm´alnˇe by se pˇri obnovˇe nastavila implicitn´ı NULL hodnota a vˇse by vy ´ustilo v chybu, protoˇze sloupec samozˇrejmˇe nepodporuje NULL hodnoty. N´astroj ˇreˇs´ı tuto situaci pr´avˇe n´astaven´ım uˇzivatelem zadan´e v ´ychoz´ı hodnoty dan´eho sloupce. Po zad´an´ı v ´ychoz´ı hodnoty se jeˇstˇe samo o sobˇe nic nestane ani nevyˇreˇs´ı. Tato hodnota se mus´ı jeˇstˇe nastavit v datab´azi. Toho dos´ahneme n´asleduj´ıc´ım SQL dotazem.

1 command=new SqlCommand(”Alter table @tableName add constraint default value @column name default ”’@defaultValue’” for @column name’, connection);

2 command.ExecuteNonQuery();

V ´ypis 12: Nastaven´ı v ´ychoz´ı hodnoty

Pouˇzijeme SqlCommand, kter ´y inicializujeme SQL pˇr´ıkazem. Pomoc´ı alter table zmˇen´ıme n´ami poˇzadovanou v ´ychoz´ı hodnotu. Pˇrid´ame nov ´y constraint s n´azvem default value a n´azvem sloupce. Promˇenn´a defaultValue je v ´ychoz´ı hodnota, kterou zad´a uˇzivatel do konzole. Dan ´y pˇr´ıkaz spust´ıme pomoc´ı funkce ExecuteNonQuery. Tento proces opaku-jeme pro kaˇzd ´y dalˇs´ı sloupec, kter ´y nem´a nastavenou v ´ychoz´ı hodnotu.

5 Z ´av ˇer

Hlavn´ım c´ılem bakal´aˇrsk´e pr´ace bylo vytvoˇrit n´astroj k z´alohov´an´ı a obnovˇe dat. N´astroj dok´aˇze pracovat s libovoln ´ym Microsoft SQL serverem a plnit bez probl´em ˚u zadan´e c´ıle bakal´aˇrsk´e pr´ace. Vhodn´e textov´e form´aty pro dalˇs´ı implementaci jsme probrali v prvn´ı kapitole Rovnˇeˇz je n´astroj rozˇs´ıˇren o moˇznost transformace. V ´yhodou n´astroje je oˇsetˇren´ı i situac´ı, kdy ubylo nebo pˇribylo v´ıce sloupc ˚u najednou. S detailnˇejˇs´ım rozborem trans-formace jsme byli sezn´ameni v uk´azkov´em pˇr´ıkladˇe a tak´e v posledn´ı kapitole. Dalˇs´ı v ´yhodou n´astroje je plnˇe automatizovan´e pˇrihl´aˇsen´ı na server. U aplikace je tak´e oˇsetˇren vstup uˇzivatele.

Nab´ız´ı se r ˚uzn´e moˇznosti rozˇs´ıˇren´ı n´astroje. Napˇr´ıklad by mohl b ´yt v budoucnu rozˇs´ıˇren o moˇznosti rozs´ahlejˇs´ı manipulace se sch´ematem libovoln´e datab´aze.

6 Reference

[1] Esposito, Dino, XML: efektivn´ı programov´an´ı pro .NET. Grada Publishing, 2004. ISBN 80-247-0775-6

[2] XML specifikace, http://www.w3.org/XML/

[3] XML validace, http://www.w3schools.com/xml/xml validator.asp [4] XmlTextWriter, http://msdn.microsoft.com/cs-cz/library/

system.xml.xmltextwriter.aspx

[5] YAML, http://www.zdrojak.cz/clanky/

yaml-serializacni-format-pro-ukladani-dat/

[6] YAML syntaxe, http://en.wikipedia.org/wiki/YAML [7] JSON, http://www.json.org/json-cz.html

[8] JSON syntaxe, http://json.org/example.html

A Elektronick ´e pˇr´ılohy na CD

Zde je uvedena adres´aˇrov´a struktura a d ˚uleˇzit´e soubory pˇrikl´adan´eho CD.

• Bakal´aˇrsk´a pr´ace

backup xml - sloˇzka s aplikac´ı

- Z´alohy - sloˇzka pro XML soubory - Skripty - sloˇzka s SQL skripty

- obnova.bat, zaloha.bat - d´avkov´e soubory pro uk´azkov ´y pˇr´ıklad BP.pdf - tiˇstˇen´a verze v elektronick´e podobˇe

Powiązane dokumenty