Avatar billede madand Nybegynder
19. august 2010 - 09:26 Der er 23 kommentarer og
2 løsninger

Parse Excel doc. til MS SQL

Hej Eksperter,

Jeg sidder og laver en console app, i får lige koden her:
http://pastebin.com/SL3ZYTvD

Det går ud på at jeg skal parse et excel ark, som indeholder en masse kunder samt data på disse kunder til en MSSQL database.
Jeg har oprettet en database med alle de korrekte datatyper.

Måden det kommer til at foregå er at en bruger extracter fra en applikation til Excel, gemmer dokumentet og klikker på min console app, som så vil løbe arket igennem og opdatere databasen.

Som min applikation er nu, så får jeg alt data udskrevet i min console og det spiller. (Jeg har for sjov skyld lige smidt connection.State() ind i mit loop for at se om jeg havde forbindelse :).

Kan i hjælpe mig videre herfra? Jeg skal til at smide det ind i SQL, men er lidt på bar bund om hvordan jeg bedst muligt kan gøre det.

Har i nogle bedre forslag til hvordan jeg skal lave min applikation, er i velkomne! :)
Hvordan ville i gøre det?

Mvh,
Avatar billede lasserasch Juniormester
19. august 2010 - 11:36 #1
Enten skal du slette hele SQL tabellen og lægge alt ind fra nyt hver gang, ellers skal du have en eller anden form for identifier så du i din kode kan finde eksisterende rækker i SQL databasen og holde dem op mod dit Excel ark.


Men jeg er ikke helt sikker på at jeg forstår dit spørgsmål. Leder du efter et eksempel på hvordan du kommunikerer med en SQL server eller hvordan?

Mvh.
Lasse
Avatar billede janus_007 Nybegynder
19. august 2010 - 12:49 #2
madand-> Sidder du med en SQL Server og hvilken version?
Avatar billede madand Nybegynder
19. august 2010 - 13:06 #3
lasserasch: Jeg er faktisk mest ude efter best practice, for jeg har ikke lavet noget lignende før. Men vil det være nemmest at slette alt data i tabellen og så smide det nye ind bagefter fra excel arket?

janus_007: Ja jeg sidder med en SQL Server 2008 Express. :)
Avatar billede Syska Mester
19. august 2010 - 13:28 #4
Ja, det vil klart være nemmest at slette alt først ... men men

1. Har du foreign keys, så kan du ikke.
2. Hvis du ikke har foreign keys, så mister du måske historisk data, og du burde måske "flag" rows som deleted, hvis de ikke bruges mere eller måske senere kan blive aktive.

Jeg er mest til ... search&replace ... og indsæt nye, så du stadig har historisk data.

Men det hele kommer jo selvfølgelig an på hvad hele systemet skal kunne.

mvh
Avatar billede lasserasch Juniormester
19. august 2010 - 13:54 #5
Jeg har lavet noget lign. for flere af mine kunder og der må jeg indrømme at det blev en slet alt og genindsæt i SQL tabellen løsning.

Det er desværre ofte sådan nogle løsninger man er nødt til at lave når data kommer fra et excel ark. For du har som regl ikke noget unikt ID at holde rækkerne op imod i din SQL tabel.

Men jeg er enig i at en "opdater kun det ændrede og indsæt nye records" løsning absolut er det bedste hvis dit datagrundlag giver mulighed for det.

Mvh.
Lasse
Avatar billede Syska Mester
19. august 2010 - 14:12 #6
Jeg vil antage der var noget som var unikt.

Firma navn eller andet i hvert fald bare for at holde historikken i din data.

Men igen, hvad skal de data bruges til ... bliver de refereret fra andet steder, så kan man jo ikke bare slette. Men er det et "read and forget" system, og de data ikke bliver brugt i andre tables, så ville jeg klart lave det som lasse skriver.

mvh
Avatar billede madand Nybegynder
19. august 2010 - 14:21 #7
Rigtig gode løsninger i kommer med. Jeg må ærligt indrømme at jeg var på bar bund, men dette giver mig helt sikker noget at arbejde med. Systemet som vi extracter fra, er AS/400 (muligvis DB2? så gammel er jeg ikk :$) hehe.. Ud til excel, videre ind i MSSQL database og her bliver det præsenteret i nogle tabeller på en webside. Der skal ikke kunne skrives, rettes eller noget som helst fra denne webside. Udelukkende læsning fra databasen. Så det er klik på en kunde og se hvad denne kunden indeholder. Siden er lavet, men jeg prøver at spare mig selv for at skulle opdatere databasen manuelt hver gang der sker en ændring. Derfor skulle denne app, gerne automatisere det.

Jeg prøver mig lige frem med at tjekke for nye records, og ellers må det blive ryd tabel og genindlæs. Jeg vender lige tilbage, tusind mange tak.
Avatar billede madand Nybegynder
19. august 2010 - 14:22 #8
nåh ja! jeg har ingen foreign keys. Det er kun én tabel der bliver brugt forløbig :)
Avatar billede Syska Mester
19. august 2010 - 14:57 #9
svar
Avatar billede lasserasch Juniormester
19. august 2010 - 15:33 #10
Hmmm, hvis dit datagrundlag er AS/400 hvorfor overfører du så ikke direkte til SQL databasen?

Der findes en ODBC connector så du kan trække direkte ud fra AS/400 til SQL jo.

Det har jeg brugt mange gange før og det virker super godt.

Mvh.
Lasse
Avatar billede madand Nybegynder
19. august 2010 - 15:37 #11
Det var også meningen med applikationen, men der skal store ord til for at få lov til dette desværre :-/

Så derfor dette work around.
Avatar billede janus_007 Nybegynder
19. august 2010 - 22:50 #12
Man overfører sjældent data direkte til noget produktionssystem.
lasserasch, problemer kan hurtigt opstå med diverse locks osv. meget afhænger af datastørrelser, konverteringer mv. Noglegange går det godt andre gange skidt, man er bedre tjent med at lave det korrekt :)

Det med at slette alt og genindsætte er ubrugeligt når du arbejder med PK-FK og hvem gør ikke det?

madand -> Du var ude efter best practice, den får du så her :)

Det som du er ude efter er et simpelt ETL-system, det er såmænd ikke så svært.
ETL -
Extract, her henter du data ud fra Excel, kunne også være AS400
Transform, hvis dine data ikke lige er som de skal være, typisk datoformater, decimaler osv.
Load, her populerer du eksisterende system med ny data, insert/ updates.

Du skal bruge et Staging-area, et sted du smider dine data ind direkte fra Excel eller AS400

Og så ellers bare merge, dvs. enten brug merge i sql eller skriv en full outer join og find ud af hvad der skal updates, insertes eller slettes.
Avatar billede madand Nybegynder
19. august 2010 - 23:04 #13
Præcis, de er ikke meget for at give mig adgang til den store kundebase, så derfor må dette være udvejen! Fedt du gad tage dig til til at skrive hele "proceduren"! Tusind tak! Sorry guys, men Janus kom med et ret godt svar. Smider du svar? :) tak til alle!!
Avatar billede Syska Mester
19. august 2010 - 23:19 #14
janus:
korrekt, men nu siger manden jo at han har et excel ark, ingen keys, data skal bare dø når der opdateres. Så ville jeg klart bare lave en truncate table, og derefter bulk insert.

SqlBulkCopy ( mener jeg klassen hedder i .NET )

Men ETL var også hvad han reelt set var endt på, som jeg lige kan se det, men rart med lidt ekstra detaljer.

En ting jeg dog ikke helt kan se ... hvor er forskellen mht til din første kommentar.

AS400 -> Excel -> parse -> Sql ...
eller
AS400 -> parse -> Sql ...

Udover du har en mere fejlkilde mere hvor excel er inde i billedet.
Avatar billede janus_007 Nybegynder
20. august 2010 - 00:24 #15
buzzzz-> Ingen keys, næh det ved vi jo ikke, men de skal medtages i udtrækket, der skal findes noget unikt, ellers er det svært at opdatere og faktisk også vise noget brugbart :) Medmindre man er ligeglad med dubletter og hvis man kan påvise dubletter så har man også en composite key og så kan den bruges *GG*

AS400->Excel, nu ved jeg ikke hvorfor der lige er valgt Excel, det havde måske været nemmere med CSV. Fra en As400 til CSV skriver man jo blot:
CPYTOIMPF FROMFILE(*LIBL/DTAFIL) TOFILE(USER999/CSVPC)
CRTPF FILE(USER999/CSVPC)
*GG* og så gider jeg ikke paste mere fra Basic As400 tips :)

Men madand må ikke få direkte adgang, hvilket jo er ret normalt hvis det er en produktions database.

AS400->parse, mener du ikke AS400->Extract->Transform->Sql? Og jo.. det kan godt lade sig gøre, men man får jo hurtigt bygget noget som skal compiles ved ændring. Det er selvfølgelig en smagssag, men jeg kan godt li at holde tingene adskilt, altså ud af sourcen, ind i en eller flere tabeller og herefter gøre hvad der skal gøres med T-sql. Afhængig af datamængder kan det faktisk være meget omfattende at bygge et ETL som skal fungerer uden at loade 27millioner rækker ind i memory og først derefter smide dem til target. Så kan man jo naturligvis batche det osv., men alt i alt skal der jo skrives noget kode.

Man kan kigge på Rhino ETL hvis man vil have noget som spiller og kan programmeres på i C#
Hvis man bare vil følge Microsoft så skal man igang med Integration Services.
Avatar billede Syska Mester
20. august 2010 - 00:38 #16
Uden at læse det hele igennem igen, mener jeg han skrev at han ikke havde noget at sammenligne med, udover firma navne etc. som jeg lige har forstået det, så reelt set er der intet unikt.

Ja, kan godt se problemet hvis der er 27mill, men det problem vil jo også være der når excel dokumentet skal laves :-)

Nu er parse i min verden næsten det samme, men jeg kan selvf godt se forskellen ...

Ayende ... hep hey

mvh
Avatar billede lasserasch Juniormester
20. august 2010 - 08:24 #17
Janu_007 --> Måske misforstår jeg dig, men synes din tone at skrive i er unødvendig arrogant.

Jeg har ikke skrevet at han skulle have direkte adgang til as/400 fra sin applikation. Jeg har bare sagt at det ville være nemmere at eksportere de tabeller han havde brug for automatisk til SQL.

Det er et SQL job med ODBC adgangen som jeg taler om og det er gjort en million gange før og ER best practise, eller i hvert fald en officiel og alm. fremgangsmåde.

Mvh.
Lasse
Avatar billede Syska Mester
20. august 2010 - 09:46 #18
janus_007's måde at skrive på, kan godt virke arrogant, det har jeg i hvert fald lagt mærke til, gennem flere spørgsmål, men det er specielt ikke hans hensigt at være sådan, Inderst inde er han helt sikkert en blød og kærlig person :-) *heheh*

Mange ting kan gøres besværligt ... dog kan det ske at være best practice, hvis der er 27 mill rows. Men sølle 10k rows, burde ikke tage mere end 1-2 sek at få ud ... og så vil jeg sige at implementere et ETL er overkill, hvis det kan klare med en
"select * from into bla"

Men det er selvf bare min mening om det.

Ting skal laves så det passer ind ... og da vi ikke kender context specielt godt, så vil jeg mene det ikke er nemt at give "Best pratice" råd ...

mvh
Avatar billede madand Nybegynder
20. august 2010 - 10:39 #19
Nu nævner i også .CSV det kan jeg sagtens extracte til? Ville det være nemmere for mig at kode det?
Avatar billede madand Nybegynder
20. august 2010 - 10:57 #20
I kommer med rigtig mange gode forklaringer.. Puha er lidt forvirret. :D

Jeg tror sgu det nemmeste er at jeg laver en truncate table, og hvis dette ikke løser mit problem godt nok, så hopper jeg over på en af jeres andre forslag.

Ved nærmere eftertanke så virker janus's forslag lidt overkill til min app. Måske fordi jeg stadig er ny i det :)

I skal have tusind tak for jeres response.

lasse og buzz kommer begge med truncate table, så smider du (lasse) lige et svar også, så kan du og buzz dele?
Avatar billede lasserasch Juniormester
20. august 2010 - 11:09 #21
svar :-)
Avatar billede madand Nybegynder
20. august 2010 - 11:11 #22
Lasse: Du glemte at oprette det som svar :)
Avatar billede janus_007 Nybegynder
20. august 2010 - 12:53 #23
Hej alle sammen

madand-> Du spurgte efter best practice og fik den, at du så ikke følger den.. tjaaa.. det er op til dig :)
Og ja CSV er meget nemmere at parse ;) end Excel, det kan du gøre med en simpel StreamReader el.lign

buzzzz-> tak for de søde ord og godt gennemskuet :) btw. en select into er ganske fin og det er netop også tanken at lave noget sådant i det øjeblik data er kommet ind på target. Om det er en into eller full outer join med insert er jo detaljer, alt er muligt når bare data ligger i databasen :)

lasse-> Det er aldrig min mening at virke arrogant, hvad skulle der komme ud af det? Men jeg gider sku heller ikke danse om den varme grød og derfor siger jeg tingene lige ud, upædagogisk "ja", frem til målet i en fart "ja". Jeg hørte blot ingen argumenter fra dig, derfor argumenterede jeg for at gøre tingene korrekt, det er ikke arrogant :)

"Det er et SQL job med ODBC adgangen som jeg taler om og det er gjort en million gange før og ER best practise, eller i hvert fald en officiel og alm. fremgangsmåde."
- Og nej ;) Fremgangsmåden er implementeret mange gange og lavet om ligeså mange gange :) Men vi taler formentligt ud fra forskellig opfattelse af hvad mange rækker er og hvordan ETL skal implementeres.
No hard feelings :)
Avatar billede janus_007 Nybegynder
20. august 2010 - 12:58 #24
Jeg kan da lige tilføje.. at jeg ODBC adgang eller whatever direkte adgang til sourcen kan give problemer, dels mht. datamængden men også friheden til at skrive diverse joins på kryds og tværs og totalt lægge sourcen ned. Det er dumt og man får kun på puklen af DBA'erne fra sourcen, derfor er man bedre tjent med exports som de enten skriver eller blot hente nogle filer og så tage den derfra. Et andet argument kunne også være.. hvis nu mange skal hente samme data, vil man så tillade joins på kryds og tværs, fremfor at fremstille en fil som consumeren kan hente ind?

Nåh.. nu har jeg snakket nok om det :)
Avatar billede Syska Mester
20. august 2010 - 17:25 #25
svar.

Så lidt janus ... men der er nu også lidt forskel på at sige tingene som de er ...

mvh
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester