[ itf @ 17.02.2011. 12:43 ] @
Primjetio sam da MS Access baza ne dopušta višestruke insert upite kao npr. MySQL gdje je to sasvim normalna stvar.

Moj problem je što imam oko 65000 sql insert izjava koje bi htio izvršiti čim brže nad Access bazom. Koristim C++ i jedino rješenje mi je petljom izvršavati insert jedan po jedan, a to je zaista jako sporo. Da li je moguće napraviti nekakav sql upit koji bi odjednom ubacio svih tih 65000 zapisa koje ja trebam, a da radi nad MS Accessom?
[ Getsbi @ 17.02.2011. 14:19 ] @
To što si primetio nije posledica INSERT INTO u query-ju već, verovatno da imaš PK nad nekom kolonom u ciljnoj tabeli, te Access ne dozvoljava dupliranje zapisa iz izvorne u ciljnu tabelu, po toj koloni. INSERT INTO radi ineče, upravo to što od nje zahtevaš, bez obzira na broj ponavljanja upita.
[ itf @ 17.02.2011. 14:24 ] @
Nije riječ o tome već o jednom query-u koji sadrži više insert naredbi.
[ Getsbi @ 17.02.2011. 14:36 ] @
Napiši sintaksu tog query-ja, da vidim šta pokušavaš.
[ itf @ 17.02.2011. 14:49 ] @
INSERT INTO Table1 ( ColA ) VALUES (123);
INSERT INTO Table1 ( ColA ) VALUES (456);

Table1 je prazna tablica s ID (autonumber) kao PK.
[ biske86 @ 17.02.2011. 14:54 ] @
Jel tebi treba:

Code (sql):

INSERT INTO Table1 (ID) VALUES (123), (456), (344), (233);
 
[ itf @ 17.02.2011. 14:57 ] @
Ne radi niti to. To sve inače radi na nekoj boljoj bazi tipa Mysql Sql server i sl., ali ne i u accessu.
[ biske86 @ 17.02.2011. 14:59 ] @
Da, znam. Ja sam samo hteo da kažem Getsbiju šta tebi treba.
[ Getsbi @ 17.02.2011. 15:08 ] @
Jedino da te vrednosti staviš u tabelu, a onda uradiš INSERT INTO.. SELECT...FROM. Tih 65000 zapisa su verovatno negde u tabeli. To je upravo ono na čega sam prvo pomislio kad si postavio pitanje.
[ itf @ 17.02.2011. 15:13 ] @
Nažalost, ja programski (u svojoj EXE aplikaciji) generiram vrijednosti koje onda trebam prebaciti u bazu. Meni nije problem programski generirati bilo kakav sql upit, no prisiljen sam insert upite izvršavati jedan po jedan, a ne sve njih kao dio jednog velikog sql upita.
[ MarkoBalkan @ 17.02.2011. 16:09 ] @
a zašto access?

probaj sa firebird embeded bazom ili sql lite.
[ itf @ 17.02.2011. 16:25 ] @
Access mi je nekako najpogodniji jer za njega jedino trebaš DB Jet provider koji je uvijek instaliran u windowsima po defaultu. Za ove druge baze mi je uvijek upitno da li će raditi samo od sebe ili moram klijenta tjerati da još instalira milijun drugih stvari.
[ MarkoBalkan @ 17.02.2011. 17:56 ] @
stavi sql lite i driver za bazu i to je to.

jer ako za bazu koristiš access prepostavljam da će aplikaciju koristiti jedna osoba, onda si mogao cijelu aplikaciju napraviti u access-u.
[ itf @ 17.02.2011. 18:17 ] @
Eh, u tome i jest stvar što ja želim izbjeći instaliranje bilo kakvih drugih drivera, klijenata, servisa itd. Za Access bazu po defaultu je sve uvijek u samim windowsima i sve radi. Čak ne treba imati ni samu MS Access aplikaciju da bi koristio tu bazu.

A sama aplikacija je već stvar za sebe niti ima veze s accessom. Access baza mi samo treba za pohranu podataka.
[ MarkoBalkan @ 17.02.2011. 18:46 ] @
mislim da sql lite nema instalacije nego je samo file koji distribuiraš sa exe file-om kao i driver(dll file).
kad napraviš build sve ti bude recimo u release file-u i to samo proslijediš klijentu.

[ izonic @ 18.02.2011. 11:34 ] @
Access ne dopusta visestruki insert ukoliko se radi o vanjskim vrijednostima, medjutim ukoliko se radi o prebacivanju iz tabele u tabelu to je moguce izvesti i to je vec zakljuceno cini mi se.
Ovdje se namece pitanje zasto to treba i jeli za jednokratnu upotrebu?
Ukoliko imamo neke podatke iz druge baze onda nam nije bitna brzina jer cemo to prenijeti mi i to jedanput i nece operater app. to koristiti.
Ukoliko se radi o izracunatim podacima kao sto se to navodi gore onda ne vidim potrebu ih zapisivati jer nevjerujem da racunanje tako dugo traje da se bas mora zapisati zmog toga da nebi opet gubili vrijeme kada nam to zatreba.
Bolje je zapisati parametre na osnovu cega smo to izracunali pa pokrenuti kad. nam zatreba.
Ako to ipak radimo radi prikaza na monitoru (tabelarni prikaz) i to nije razlog jer u c-u moze se to lagano napraviti.

Ako sad i pored ovoga zelis se odluciti da to zapises u bazu onda ne vidim razlog da to bude sporo ako u petlju stavis ovako:
"INSERT INTO ImeTabele(Polje1,Polje2)
VALUES(" Variabl1 "," Variabla2 ")"
Vrijednosti varijabili bi se mijenjale kroz petlju na osnovu koje se dobijaju podaci.

Opet napominjem da ako se radi o izracunatim podacima kako se tvrdi drugoga nacina i nema.
Suludo bi bilo sve te podatke zapamtiti u memoriji pa ih tek po izvrsenju cijelog koda zapisati.

Ako se ipak radi o podacima iz druge baze sto i pretpostavljam i koji su zapisani kao SQL onda ovo gore navedeno bilo izvodivo jer bi kodom vadio vrijednosti iz txt fajla.
Za to se ima potreba ako nisu dostupni ovi podaci na toj (SQL, MySQL) ili nekoj drugoj bazi a ako jesu onda se sa baze boze zapisati file txt koji ima strukturu baze i onda to prihvatati u Access bazi i to ide jednostavno.

Nadam se da sam pomogao.
[ itf @ 18.02.2011. 13:10 ] @
Citat:
izonic:...
Bolje je zapisati parametre na osnovu cega smo to izracunali pa pokrenuti kad. nam zatreba.
Podaci koji se generiraju imaju "random komponentu" pa to nažalost nije moguće...

Npr.: Aplikacija A u jednom trenutku za sve studente slučajnim odabirom generira brojeve zadataka koje pojedini student treba rješiti. Znači, svima su unaprijed poznati njihovi zadaci i u isto vrijeme. Aplikacija B pri validaciji rješenja tih zadataka mora nekako znati koje je zadatke dobio koji student te stoga trebam bazu da to spremim.
[ mkaras @ 18.02.2011. 14:33 ] @
@itf:
U prvom postu je rečeno da treba oko 65000 inserta u bazu. Koliko je to
vremenski? Koji algoritam koristiš za unos podataka?
Pošto si rekao da koristiš C++ pretpostavljam da koristiš i ADO
biblioteku tako da nema nikakvih problema da se konektuješ na bazu,
otvotiš tabelu, u petlji uneseš šta hoćeš, zatvoriš tabelu i
diskonektuješ bazu i gotovo.Od toga brže ne može.
Ne vidim razlog da insistaraš na SQL-u

[Ovu poruku je menjao mkaras dana 19.02.2011. u 01:21 GMT+1]
[ itf @ 18.02.2011. 15:16 ] @
Vremenski traje par minuta jer, kao što sam gore napisao, sekvencijalno izvršavam jedan po jedan sql upit. Zato i tražim rješenje da odjednom (ili barem nekako brže) sve prenesem u bazu.
[ mkaras @ 18.02.2011. 15:18 ] @
Kako glasi algoritam po kome radiš? Bez koda, samo opisno
[ itf @ 18.02.2011. 15:28 ] @
Algoritam (postupak) si ti već napisao. Otvori se tablica i for petljom jedan po jedan...
[ MarkoBalkan @ 18.02.2011. 16:23 ] @
probao sam sa sql lite, on je još sporiji.
[ izonic @ 18.02.2011. 20:25 ] @
Sporost operacije nije u zapisu. To sto spominjes koliko imas redova nikako nesmije toliko trajati i na naj losijem racunaru.
Tvoja porost je u kodu.
Evo da pokusam dokuciti.
Imas tabelu ucenika koju noras podici kao recordset i pokrenuti u petlji.
Unutar ove petlje imas tabelu pitanja koja bi se trebala zavrstiti ili pak ovdje generises slucajan broj koji ide u rasmonu od 1 do broja rekorda u tabeli pitanja a petlja se krece u rasponu od 1 do broja pitanja za jednog ucenika.
I to nebi bio neki problem da nije toga da se pitanje nesmije ponoviti a slucajan broj itekako se hoce ponoviti pa onda moras ispitivati jeli se ponovio pa ako jeste onda preskaces i to traje vjecnost.
Umjesto ovoga mozes podisi recordset za svakogo ucenika sa random slaganjem.
Onda ti vise netreba radom u kodu nego jednostavno napravis drugu petlju da se krece do broja pitanja za jednog ucenika i ne preskaces recordset nego redom prepisujes.

Drugo je pitanje kako napraviti random odnosno slucajan broj ako znamo da slucajan broj i nije bas slucajan.
Dobro da vidim dovdje jesam li na pravomtragu.

[ itf @ 18.02.2011. 22:07 ] @
Sporost je u kodu, ali samo iz razloga jer se podaci sekvencijalno upisuju u bazu. Generiranje i odabir slučajnih brojeva se može vremenski zanemariti jer od 200 zadataka vrlo rijetko se dogodi da se u 10 slučajno odabranih nađu 2 ili više istih pa da se taj proces treba ponoviti. Čak i ako zanemarimo generiranje slučajnih brojeva i u bazu (tablicu) upisujemo samo konstante (npr. broj 1 u svaki redak) to traje oko 3-5 min za 65000 zapisa.
[ mkaras @ 18.02.2011. 22:37 ] @
On 18.2.2011 16:28, "itf" wrote:
Citat:

Algoritam (postupak) si ti već napisao. Otvori se tablica i for petljom
jedan po jedan...
--


Ako si koristio algoritam koji sam naveo u prethodnom postu onda brže od
toga ne možeš. Pokušaj da malo drugačije sagledaš problem. Možda da se
pripreme grupe zadataka ranije pa da se u datom trenutku samo podele.
[ banem @ 18.02.2011. 22:44 ] @
Ja bih ipak glasao za SQL. 65000 zapisa za 3-5 minuta je očajno sporo, šta bi se tek desilo da je to u mreži sa više korisnika, trajalo bi pola sata.

Dopuna: sećam se da sam ranije, imam to negde, napravio jedan program koji generiše slučajne brojeve i popunjava bazu. Upisivao je oko milion zapisa za vrlo kratko vreme, minut dva možda. Ta tabela mi je trebala za testiranje nečeg drugog.
[ banem @ 18.02.2011. 22:52 ] @
Hmm... ja mislim da sporo radi, jer svaki čas otvaraš i zatvaraš ado konekciju ka bazi. Sam SQL radi kao munja, problem je konekcija.

Zaobilazno bi mogao da napucaš prvo jedan TEXT fajl i onda otvoriš ADO konekciju i prepišeš iz TXT u MDB. To bi trebalo da se desi u roku od sekund-dva.
[ izonic @ 18.02.2011. 22:54 ] @
Jesil probao sa recordsetovima. Nisi rekao ni koju konekciju koristis.
Najbolje bi bilo kad bi vidjeli kod.
Ovako je bespredmetno dalje. Pretpostavljam da jos dvije tabele podizes prije a to je tabela ucenika i tabela pitanja.
[ mkaras @ 18.02.2011. 23:50 ] @
Upravo probano sa Datanamic DB Data Generator MultiDB Edition 2.2.1. Reč
je o Access-u 2003 i tabeli sa poljima ID(AutoNumber), nesto(text,50).
generisano je 100 000 redova sa popunjavanjem tabele slučajnim tekstom
sa uvek istim brojem znakova (50), za nekih 100 sekundi. Kada je polje
nesto(integer) generisanje 100 000 zapisa traje samo 3(tri) sekunde.
Negde u kodu postoji sistemska greška koja krade vreme
[ banem @ 19.02.2011. 00:08 ] @
To radi drugačije, ne otvara i zatvara konekciju za svaki zapis.
[ itf @ 19.02.2011. 07:12 ] @
Koristim ADO.

Pseudo kod:

Code:
Otvori konekciju prema bazi
za i=1 do 65000
     dodaj zapis(i)
Zatvori konekciju


Inače, moja je greška što nisam primjetio da je program zapravo jako spor jer aplikacija je pokrenuta u IDE-u. Izvan njega treba joj 50 sec... I to je sporo, ali ipak puno bolje.