[ teri_kalijer @ 12.10.2016. 11:27 ] @
Potrebna mi je pomoć sa problemom na koji sam naišao kod INSERT-a grupe slogova u tabelu.

Ako se ne varam, u MS SQL Serveru, pri INSERT-u grupe slogova u tabelu (INSERT INTO ... SELECT * FROM), zbog atomičnosti transakcije, ako neki od slogova nije ispravan iz ovog ili onog razloga, cela grupa slogova biće odbačena.
To je u redu.

Sad, imam neku veću obradu: učitavanje slogova u bazu iz gomile XML fajlova. XML fajlovi se parsiraju i podaci iz njih se učitaju u privremene tabele, zatim se iz njih, ako podaci već ne postoje u bazi, kroz SELECT * radi INSERT slogova u bazu, u mnogobrojne stalne tabele.

Bilo bi poželjno da, pri tom 'grupnom' INSERT-u slogova iz privremenih u stalne tabele, ako neki od slogova nije ispravan, ne budu odbačeni svi slogovi, već samo neispravni.
Tako da je moje glavno pitanje: da li je to moguće - nekako 'reći' MS SQL-u da, pri jednom 'grupnom' INSERT-u, odbaci samo te neispravne slogove, a učita ispravne?

Alternativa mi je da učitavanje radim 'pešaka': kroz petlju čitati slog po slog iz privremene tabele, započeti transkaciju, zatim pokušati INSERT u stalnu tabelu. Ako nema greške, COMMIT-ujem transakciju i čitam novi slog, u protivnom hendlujem neispravni slog. Međutim, to bi dosta usporilo obradu, koja je i ovako zahtevna.

Zbog prirode obrade i brojnih INNER JOIN-ova koji se, tokom učitavanja, uspostavljaju između privremenih i stalnih tabela, BULK INSERT nije zgodna opcija.
[ jablan @ 12.10.2016. 12:31 ] @
A zašto ne pokušaš da doradiš svoj SELECT tako da ne vuče recorde koji nisu validni?
[ teri_kalijer @ 12.10.2016. 13:30 ] @
Hvala ti na odgovoru :).

Ne dorađujem SELECT zato što ima veliki broj tabela u koje se podaci učitavaju i njihove relacije su složene. Bilo bi potrebno poći od tabele do tabele, analizirati strane ključeve i sva postojeća ograničenja na poljima tabela i ugraditi sve to u SELECT naredbe da bi dobili garanciju da neće doći do pucanja pri INSERT-u. Jer kad krene INSERT, milion slogova recimo, dovoljno je da jedan slog ima jedan nevalidan podatak i SVI slogovi biće odbačeni. Tuga.

Kako god, izgleda da me to očekuje - da pođem od tabele do tabele i dorađujem SELECT - jer ne vidim jednostavnije rešenje koje bi bilo dovoljno efikasno. Ipak, pre nego što krenem tim (mukotrpnim) putem, želeo sam da proverim podržava li MS SQL opciju da pri grupnom INSERT-u budu odbačeni samo nevalidni slogovi.
[ jablan @ 12.10.2016. 14:50 ] @
Takođe, malo mi je sumnjivo da je ubacivanje slog po slog TOLIKO sporije od ubacivanja jednim upitom. Prvo bih to empirijski proverio. Takođe, prednost izvršavanja upit po upit je i to što imaš individualne poruke o greškama.

BTW, MSSQL ima dobru podršku za stored procedure, tako da sve individualne upite možeš da pokreneš na samoj bazi. U tom slučaju bi me baš začudilo da je dužina obrade znatno duža nego jednim upitom.
[ mmix @ 12.10.2016. 16:23 ] @
Brzina je priblizno ista ako radis u okviru iste transakcije, u surpotnom svaki insert vuce svoj zaseban locking, sto dotano usporava. Jedino sto nema sanse da to primeti ljudski operater, posto pricamo o mikrosekundama.

I naravno da moze da se radi selekcija u insert po "nekoj validnosti". Insert ne radi samo sa statickim izvorom podataka, moze podatke da vuce iz select podquerija: https://technet.microsoft.com/en-us/library/ms189872.aspx
jednostavno stavi svoj kriterijum u WHERE unutar SELECT-a
[ jablan @ 12.10.2016. 16:31 ] @
Mislim da zna on to, ali ima previše constrainta koje bi morao da prepiše u SQL. Ovako mu lakše - zahvati sve, sipa u INSERT pa šta prođe, prođe. ;)
[ anon115774 @ 12.10.2016. 19:25 ] @
A koja je definicija "neispravnog sloga"?

Uradis update na privremenoj tabeli i oznacis (u novoj koloni) sve one neispravne i onda sa svim ostalim uradis insert into.
[ teri_kalijer @ 13.10.2016. 13:58 ] @
Citat:
jablan:
Mislim da zna on to, ali ima previše constrainta koje bi morao da prepiše u SQL. Ovako mu lakše - zahvati sve, sipa u INSERT pa šta prođe, prođe. ;)


Upravo tako ;).


Solidno poznajem mogućnosti SELECT naredbe, i svestan sam da je pomoću nje i dinamički kreiranog SQL koda moguće napraviti moćan upit koji bi izdvojio samo ispravne slogove, koji bi garantovano bili upisani u bazu.
Međutim, da bi se to postiglo, broj provera koje u okviru tog SELECT-a treba sprovesti je pozamašan. Takođe, ima popriličan broj tabela (oko 50) i za svaku ponaosob potrebno je napraviti specijalizovani SELECT.
Ako uzmemo u obzir da u pojedinim tabelama ima stotine miliona slogova, čitava obrada mogla bi da se poprilično oduži.

I tako, ipak ću se opredeliti za učitavanje slog po slog, u petlji, svi slogovi u okviru jedne transakcije, i hendlovanje neispravnih slogova kroz BEGIN TRY ... END TRY. Isprobao sam, nije puno sporije od 'grupnog' INSERT-a.

Jablane, Mmix, hvala vam za pomoć, puno ste mi pomogli! :)