[ *.net @ 22.07.2002. 21:12 ] @
Prosao je jos jedan dan u provaljivanju jedne linije koda i par wizarda :). I prosao je i ne mogu da verujem da mi najjednostavniji update data adaptera ne radi kako treba. Stvarno mislim da je moja beta2 nesto izakana.

Imam data adapter , data set, conn, i jednu jedinu tabelu u bazi. Proverio sam 100 puta da li mi se sve kolone i njihovi tipovi poklapaju u bazi i izgenerisanom data setu. I opet kada popunim data set sa nekolko rowova na datadapter.update mi javlja gresku. Kada stavim try blok greska glasi:
"Characters found after end of SQL statment."

Okacio sam zipovan projekat i bazu(verovali ili ne) i ako je neko raspolozen da pogleda evo adrese:
http://www21.brinkster.com/muting/problem.zip
File ima 120K.

Trebalo bi jednio podesiti ponovo putanju do baze jer je access u pitanju i jet4.

-------------------
mora desni klik pa save target as
[ degojs @ 23.07.2002. 03:28 ] @
Ja taj tvoj projekt ne mogu da pokrenem: odmah krecu neke silne greske jos u Windows Forms Designer Generated Code sekciji. Ni exe fajl nece da se pokrene.

Citat:

Stvarno mislim da je moja beta2 nesto izakana


uhh...pokusaj da nekako nabavis finalnu verziju da bar ne bi pogadjali da li je tvoj bag ili microsoftov (nije da nema bagova u verziji 1.0 ali.. :)

Uzgred, ako mi se nije prividjalo, imas 2 connection objekta (u Forms dizajneru su jedan ispod drugog, pa se cini da imas samo jedan) ???

pozdrav


[Ovu poruku je menjao degojs dana 24.07.2002 u 01:56 PM GMT]
[ *.net @ 23.07.2002. 06:45 ] @
nisam video da ima dva conn. deklarisana su dva a definisan samo ovaj moj, to je isto nesto sam uradio er sam sigurno isao samo sa popunjavanjem wizarda sa data adapter. ne definitivno moram da nabavim ovu krajnju verziju sa sve msdn.

a samo jedno pitanje koje mi je sumljivo bas za ovaj prog.
kada u bazi imam kolonu koja je auto number inkrement 1 u aksesu kada nesto dodajem sve se naravno povecava za jedan u toj koloni. dodjem na primer do 9 , i obrisem rucno u accesu sve redove, sledeci koju dodam ima number 10 i to je ok, ali kako data set da zna dokle je acces stao dok se on popunjava van konekcije sa tabelom? Da li ju tu nesto automatizovano ili mora posebo da se iskotrolise?
[ degojs @ 23.07.2002. 07:24 ] @
(ako sam dobro razumeo pitanje:)

Polje koje ti je auto-increment ne menjaj (ostavi null),a kada ti posaljes dataset u bazu, access ce sam da upise odgovarajuce vrednosti. Kolonu u kojoj su auto-increment brojevi obicno ni ne trebas da prikazes u datagrid-u jer korisnici ionako ne mogu da je menjaju, a njima sama informacija iz te kolone obicno ne znaci ama bas nista.

Citat:

ne definitivno moram da nabavim ovu krajnju verziju sa sve msdn


Preporucio bih i neku knjigu, ako ikako mozes. Evo, Dragi Tata je postovao jedan link za komplet knjigu u PDF formatu, bas za verziju beta-2 koju ti imas.

Pozdrav i ne daj se:)
[ *.net @ 23.07.2002. 15:39 ] @
U ovam primeru koji sam zamislio da napravim bi mi u principu trebala kolona autonumber u data setu. To bi bio kao nei seriski broj koji bi korisnik morao da vidi kao proveru sta je ubacio u tabelu. Da li to onda znaci da bih morao da napravim dva data seta, jedan koji se puni zajedno sa kolonoma koja je auto number i ostalim koje su potrebne i da taj data set bude izvor podataka za data grid nezavisno od drugog dataseta koji bi sluzio za punjenje podataka bez autonumber kolone?
Ili bi ispravnija mogucnost bila da imam taj data set za izvor data grida a da podatke punim (insertujem u bazu) direkltno preko nekog commanda koji ima u sebi parametare koje prosledjuje uskladistenoj proceduri u accesovoj bazi.
Ja sam malopre probao nesto kao ovo drugo resenje ali bez uskladistene procedure. Napravio sam comannd i dao mu (npr imam samo dve kolone)
command.connection = "OleDBConnestioq"
command.type = storedprocedure
comman.paremters.add("ime", System.Data.OleDb.OleDbType.Char(5))
command.text = "INSERT INTO tabela(name, broj) VALUES (ime, ?)"

i na clik nekog dugmeta
Me.OleDbConnection1.Open()
Me.comman.Parameters("ime").Value = "pera"
Me.command.ExecuteNonQuery()
Me.OleDbConnection1.Close()

mozes li mi reci gde sam pogresio? :(
[ degojs @ 23.07.2002. 16:33 ] @
Nije mi bas jasno iz posta sta zelis da postignes i kako, odnosno sam dizajn baze mi je malo nejasan.

Ovako kako vidim:
Code:

command.connection="OleDBConnecioq"

Ne. Ovim si pridruzio STRING a ocekuje se referenca na Connection objekt.
Code:

command.connection = OleDbConnection1

ce odraditi posao ako ti je to ime koneksn objekta.

Dalje, nema sta da koristis Stored Procedure, ako vec koristis INSERT izraz. Stored procedure je nesto kao rutina koju napises u samoj bazi pa je onda pozivas iz svog programa. Potpuno druga stvar. Imaju mnogo prednosti i svakako ces ih koristiti kad malo savladas ove pocetne stvari :)

I trece, naravno tip podataka mora da se poklapa sa onim u bazi.

Da vidimo mi kako bi to sve trebalo da izgleda:
Code:

Dim strSQLInsert = "INSERT INTO Table1(Name) VALUES (@parametar1)"

Dim strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data " & _
"source=x:\temp\db1.mdb;"

Dim param As OleDbParameter
Dim rowsAffected As Integer

Dim conn As OleDbConnection = New OleDbConnection(strConnection)
Dim cmd As OleDbCommand = New OleDbCommand(strSQLInsert, conn)

param = New OleDbParameter("@parametar1", OleDbType.VarWChar)
param.Value = "pera"
cmd.Parameters.Add(param)

        Try
            conn.Open()
            rowsAffected = cmd.ExecuteNonQuery()
            MsgBox("Rows affected: " & rowsAffected.ToString)
        Catch ex As OleDbException
            MsgBox(ex.Message)
        Finally
            conn.Close()
        End Try


Elem, ovo radi AKO ti je polje BROJ auto-increment, pa onda kako sam ti i napisao u prethodnom postu ne moras da nista prosledjujes u to polje, DB ce to sam da odradi.
Napominjem da je zaista pametno :))) koristiti SEH (structured error handling) - try-catch-finally-end try. Zasto? Pa nikad ne znas da li ce problem da se pojavi, a ako ces da ides pomocu command objekta, onda ovako uvek osiguras da je konekcija zatvorena blokom FINALLY koji se uvek izvrsava. UVEK je zatvori nakon rada sa bazom da bi smanjio opterecenje servera. Upravo zato se i koriste Dataset objekti, kada se pomocu adaptera automatski stvara i prekida veza sa bazom, pa ne moras da brines o tome.

Ako bi recimo imao vise kolona u tabeli koje hoces da popunis onda bi imao:
Code:

Dim strSQLInsert = "INSERT INTO Table1(polje1,polje2,polje3) VALUES (@parametar1, @parametar2, @parametar3)"

Naravno da mozes i da koristis razumljivija imena kao @Ime, @Prezime, itd. Napominjem da ako je neko polje auto-inc. (tj. Identity u SQL serveru) ne treba uopste da ga navodis nigde u INSERT izrazu - baza ce sama da ga popuni.

I naravno svaki bi parametar dodao u parameters kolekciju OleDbCommand objekta.
Code:

  param = New OleDbParameter("@parametar1", OleDbType.VarWChar)
        param.Value = "Zika"
        cmd.Parameters.Add(param)

  param = New OleDbParameter("@parametar2", OleDbType.VarWChar)
        param.Value = "Slika"
        cmd.Parameters.Add(param)

  param = New OleDbParameter("@parametar3", OleDbType.VarWChar)
        param.Value = "Uzice"
        cmd.Parameters.Add(param)

posle cega ides na izvrsavanje try-catch-finally-end try.

HTH,
dejan
[ degojs @ 23.07.2002. 18:31 ] @
Ovako, malo sam bolje prostudirao tvoje pitanje pa mi je sad valjda jasno sta zelis da uradis :) Ti hoces da dodas neke recorde u tabelu i da odmah vidis koja je vrednost dodeljena polju koje je oznaceno kao auto-increment.

NEMA potrebe da koristis dva dataseta, dva adaptera ili da koristis Command object i da izvrsavas INSERT izraz SQL-a.

Dakle, procitas podatke iz baze pomocu recimo:
DataAdapter1.Fill(DataSet1).

Kada hoces da dodas novi record (ili vise njih), mozes da prepustis da korisnik dodaje nova polja direkt u datagridu, a evo kako rucno da to uradis:
(recimo da u tabli imas polja AutoID, FirstName i LastName; AutoID polje je auto-increment):
Code:

Dim table As DataTable
Dim row As DataRow
try
table=dataset1.Tables.Item(0)
row=table.NewRow()
row("FirstName")="Zika"
row("LastName")="Slika"
table.Rows.Add(row)
dataadapter1.Update(dataset)
catch ex as SQLException  ' ili OLEDBexception
msgbox(ex.message)
end try


E sad, ako hoces odmah da ti se u datasetu (i u datagridu) prikaze vrednost polja koje je auto-increment onda dodas nesto kao ovo u RowUpdated dogadjaj DataAdaptera:
Code:

Private Sub OleDbDataAdapter1_RowUpdated(ByVal sender As Object, ByVal e As System.Data.OleDb.OleDbRowUpdatedEventArgs) Handles OleDbDataAdapter1.RowUpdated

         If e.Status = UpdateStatus.Continue Then
            If e.StatementType = StatementType.Insert Then

                Dim Command As New System.Data.OleDb.OleDbCommand("SELECT @@IDENTITY", OleDbConnection1)
                e.Row("AutoID") = CInt(Command.ExecuteScalar())

            End If
        End If
    End Sub


Nadam se da je to ono sto si trebao.

pozdrav
[ *.net @ 23.07.2002. 19:18 ] @
Ne mogu da verujem ali uspeo sam i to sa uskladistenom proceduraom. Ja sam pogresio malo u pitanju jer sam pogresno kucao neke stvari ali ono sto si mi napisao je bilo kristalno jesno ( posle 120 min gledanja sa kodom:))
slomio sam srednji taster na misu za tih 120 min al bitno da sam barem nesto ukapirao.

tnx
[ *.net @ 23.07.2002. 19:23 ] @
idem sada malo da se gledam sa ovim drugim resenjem koje si mi napisao
[ degojs @ 23.07.2002. 19:58 ] @
Ok, samo da razjasnim jos malo, ako ti vec nije zlo :)
Da bi se nove vrednosti auto-increment polja pojavile u datasetu (i datagridu) moras da pozoves update.

Mala digresija: posto radis na beta-2 verziji, mozda ne bi bilo lose da za pocetak postavis opciju Option Strict On na Off (desni klik na Project->Properties... cini mi se da je tamo:). Mada nisam siguran sta bi bilo ispravno u tvom slucaju :))

HTH



[ *.net @ 23.07.2002. 22:48 ] @
Na kraju sam odradio nesto sto nisam ni predpostavaljo da ce tako ispasti. Naime nisam stavio ni jedan data adapter sobzirom da sam citao o tome da onim pogorsavaju malo performane, a i ti se me degojs naucio onu foru da ne updejtujem ceo data set u bazu jer se setaju podaci.

Ovako data set mi se puni preko komande i data ridera jednostavno
SELECT * FROM Tabela ORDER BY Serial
i to ide relativno brzo. kada zelim da insertujem nesto u bazu onda to ide preko komande koja ima 9 parametara koji se salju u stored procedure u accesu i posle inserta se poziva ponovo funkcija sa data riderom i onim select upitom.

Razmisljao sam o ovome i o tvom resenju sa dogadjajem RowUpdate dataAdaptera i cini mi se da je fakticki isto sto se performasi tice, jer onaj data adapter takodje vrsi komandu INSERT a onaj select u u RowUpdate je isti? ili bolji ? od mog selecta to nisam siguran mada sobzirom da selektuje samo jednu kolonu.

Sigurno da imam dosta koda u odnosu na RowUpdate ali ne znam kak oto ide sa performasama. Trenutno sam veoma razocaran performansam jer kada je i 500 rdova ucitanu u datagrid iz baze vec mi secka kao da je u pitanju neka 3D igra :). Na primer pomeram prozor po ekranu i cas ga vidim u donje cas u gornje m uglu, a o skrolovanju redova u data gridu da i ne govorim.

Dok se ucitavaju podaci preko inserta stavicu progres bar da izglda svetski :) ali ipak mi sve nekako sporo radi. Da li je to tuzna realnost ADO.NET-a u kombinaciji sa Accesom ili se daj boze varam?
[ degojs @ 24.07.2002. 04:29 ] @

*.net,
pokusaj da razmislis o tome da li je potrebno da korisnik ima odjednom u datagridu 500 recorda. NAJCESCE to uopste nije potrebno. Ogranici pretragu WHERE uslovom prilikom iscitavanja podataka iz baze. Kome to treba da ima 500 recorda u memoriji odjednom, a svejedno ne moze da vidi vise od 50-ak u svakom trenutku.

Za tvoju informaciju, ja sam sad, da bih testirao malo to sto ti kazes, napunio datagrid sa vise od 2000 record-a sa jednim osrednje slozenim upitom iz baze Northwind.mdb i sa povecim brojem kolona --- ne primecujem neko usporenje :) Nemam neku zver od masine.

Ne znam kako ti stojis sa memorijom.. ali ionako nikad ne treba da racunas na to.

Medjutim, kako rekoh, razmisli o tome koliki dataset drzis u memoriji i da li je to uopste potrebno, kako rekoh - obicno nije.

I za kraj, opet bih napomenuo da koristis beta-2, koji je prepun debug instrukcija i slicno, tako da je mozda problem i u tome.

Pozdrav :)
[ *.net @ 24.07.2002. 18:22 ] @
A da li mozda postoji nacin da ucimtam podatke u data grid i potom ga odvojim data soursa i onda dataset.clear()

probao sam da odvojim u kodu sa
myDataGrid.DataSource=Nothing :)
ali onda se izgube podasi iz datagrida
[ degojs @ 24.07.2002. 19:50 ] @
Nije mi poznato kako da se izvede to sto zelis osim da koristis dva dataset-a.
Zaista ne znam sta zelis da postignes, ali cini mi se da si se malo zapetljao pa pocinjes da komplikujes. Shvati ovo kao dobronameran savet :)

pozdrav
[ *.net @ 24.07.2002. 21:38 ] @
sad mi radi sasvim ok, sve sam ponovo uradio u novom projektu i sada ne koci...
:))
dobro nemo' me brukas ovde pred svima :))
salim se