Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ODBC a powtórzenie w indeksie

67 views
Skip to first unread message

Radek

unread,
Sep 27, 2005, 8:58:51 AM9/27/05
to
Witajcie
Gdy wstawiam do pola (z kluczem) wartość, która sie powtarza to access zgłasza
błąd 3022(powtórzenie w kluczu) - można go obsłużyć i wstawić ponownie poprawną
wartość.
A jak to zrobic gdy wstawiam do tabeli połączonej przez ODBC - zawsze otrzymuje
ten sam błąd bez względu na okoliczność "Nieudane wywołanie ODBC".
Robie to poprzez DAO.
Czy jeśli zastosuję ADO to będę mógł rozróżnić numer błędu?Czy jest na to jakiś
sposób?

Pozdrawiam
Radek


--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl

Rafał Posmyk

unread,
Sep 27, 2005, 9:40:02 AM9/27/05
to
Radek wrote at Dienstag, 27. September 2005 14:58:

> ... Czy jest na to jakiś
> sposób?

F1("kolekcja Errors")

Ciao, Smyk
--
Fju fju - powiedział Ćwirek

Radek

unread,
Sep 27, 2005, 10:01:48 AM9/27/05
to

Nie wiem czy zostałem dobrze zrozumiany, ale mnie udało się przechwycic błąd
ODBC (3156 jeśli dobrze pamietam)-problem w tym
że ten błąd zwraca wiele różnych zdarzeń, a nie tylko powtórzenie w kluczu.
W związku z tym nie mogę rozróznić co było przyczyną.

Rafał Posmyk

unread,
Sep 27, 2005, 10:28:37 AM9/27/05
to
Radek wrote at Dienstag, 27. September 2005 16:01:

> Nie wiem czy zostałem dobrze zrozumiany, ...

Przeczytales ? Chyba nie skoro dalej pytasz. Eh ^k.{4}$ !

Otoz w momencie wystapienia bledu, kolekcja Errors wypelniana jest
przynajmniej jednym objekten Error. Takich bledow moze jednak byc wiecej.
W przypadku ODBC mozna tam znalezc najczesciej 3 Error'y.
Pierwszy - zwracany domyslnie - to wlasnie ow "Nieudane wywołanie ODBC".
Drugi zwracany przez warstwe menadzera zrodel ODBC a trzeci od wlasciwego
sterownika ODBC. Jesli sterownik ODBC oparty jest na natywnych bibliotekach
danego silinka (np. "ORACLE OCI" lub "Sybase OpenClient") moze byc jeszcze
czwarty Error, pochodzacy wlasnie od tej warstwy.

W przypadku bledu wartosci dla klucza/indexu, obawiam sie, ze
warstwa menadzera zrodel ODBC zwroci cos na ksztalt "Integrity constraint
violation" albo "General error". Wtedy trzeba bedzie siegnac glebiej
po trzeci albo nawet po czarty Error.

Błażej Strus

unread,
Sep 27, 2005, 2:44:39 PM9/27/05
to
>>Nie wiem czy zostałem dobrze zrozumiany, ...
> Przeczytales ? Chyba nie skoro dalej pytasz. Eh ^k.{4}$ !
> Otoz w momencie wystapienia bledu, kolekcja Errors wypelniana jest
...
A ja jeszcze dodam, że w ADO jest osobna kolekcja błędów -
Connection.Errors - też warto zajrzeć (Nie mylić z Err!).

Blazek

Radek

unread,
Sep 28, 2005, 8:12:23 AM9/28/05
to

Po krótkim zapoznaniu się myslałem że to nie to, ale jeśli tam są jakieś
poziomy to już się zabieram do pracy.

Dzięki

Radek

unread,
Oct 3, 2005, 4:18:14 AM10/3/05
to

Przeczytałem, potestowałem i stwierdzam, że mam tylko jeden błąd w kolekcji
dotyczący ODBC. Wydaje mi się, że musiałbym mieć założony Workspace (dbUseODBC)
a ja mam formularz oparty o tabelę połączoną (przez ODBC do MSSQL, Acc 97). Czy
w takim przypadku da się wydobyc komunikat o błędzie (prawdopodobnie zwracany
przez sterownik do bazy)?

Pozdrawiam

Rafał Posmyk

unread,
Oct 3, 2005, 5:01:57 AM10/3/05
to
Radek on Montag, 3. Oktober 2005 10:18 wrote:

> Przeczytałem, potestowałem i stwierdzam, że mam tylko jeden błąd w
> kolekcji dotyczący ODBC. Wydaje mi się, że musiałbym mieć założony
> Workspace (dbUseODBC) a ja mam formularz oparty o tabelę połączoną
> (przez ODBC do MSSQL, Acc 97).

To nie ma nic wspolnego z dbUseODBC. Dziala takze w kombinacji z
Jet'em. Sam sie kiedys na to zlapalem.

> Czy w takim przypadku da się wydobyc komunikat o błędzie
> (prawdopodobnie zwracany przez sterownik do bazy)?

Mozesz przytoczyc kod, ktorym sprawdzasz bledy ?

Ciao, Smyk
--
Fju, fju - powiedział Ćwirek

Radek

unread,
Oct 3, 2005, 5:50:16 AM10/3/05
to

> Mozesz przytoczyc kod, ktorym sprawdzasz bledy ?
>
> Ciao, Smyk
> --
> Fju, fju - powiedział Ćwirek

Oczywiście:

Dim liczerr as integer
On Error Resume Next
err.Clear
Errors.Refresh
Debug.Print Errors.Count
For Each liczerr In DBEngine.Errors
Debug.Print liczerr.Description
Debug.Print liczerr.Source
Debug.Print liczerr.Number
Debug.Print err.Description
Debug.Print err.Source
Debug.Print err.Number
Next liczerr

To mi zwraca jeden błąd w kolekcji.

Krzysztof Pozorek

unread,
Oct 3, 2005, 3:43:05 PM10/3/05
to
(...)

> Dim liczerr as integer
> On Error Resume Next
> err.Clear
> Errors.Refresh
> Debug.Print Errors.Count
> For Each liczerr In DBEngine.Errors
> Debug.Print liczerr.Description
> Debug.Print liczerr.Source
> Debug.Print liczerr.Number
...

> Next liczerr
>
> To mi zwraca jeden błąd w kolekcji.

Ponizej przekleilem fragment dzialajacego kodu z Accessa 97, ktory poprzez
ODBC korzysta z MsSql. Czyli Twoj przypadek... I to dziala:

Set Rs = SbF.RecordsetClone
Rs.AddNew
Rs!Lp = Rs.RecordCount + 1
Rs!DowNag = Me!DowNag
Rs.Update
If Err <> 0 Then
For i = DBEngine.Errors.Count - 1 To 0 Step -1
Set errX = Errors(i)
MsgBox errX.Description, 48
Next i
End If

Przyklad wyswietla wszystkie bledy z kolejki, nie tylko jeden ostatni. Moze
ten przyklad Ci pomoze... W sumie nie piszesz najwazniejszego - jak
aktualizujesz te tabele? Trudno, zebys tu zamieszczal caly swoj kod, ale
moze sprobujesz powyzszego sposobu? Jesli do aktualizacji bazy nie uzywasz
metod DAO, to i nie bedziesz mial bledow DAO w kolekcji DBEngine.Errors.

Krzysztof Pozorek


Radek

unread,
Oct 4, 2005, 3:20:57 AM10/4/05
to
>        Set Rs = SbF.RecordsetClone
>        Rs.AddNew
>            Rs!Lp = Rs.RecordCount + 1
>            Rs!DowNag = Me!DowNag
>        Rs.Update
>        If Err <> 0 Then
>            For i = DBEngine.Errors.Count - 1 To 0 Step -1
>                Set errX = Errors(i)
>                MsgBox errX.Description, 48
>            Next i
>        End If
>
> Przyklad wyswietla wszystkie bledy z kolejki, nie tylko jeden ostatni. Moze
> ten przyklad Ci pomoze... W sumie nie piszesz najwazniejszego - jak
> aktualizujesz te tabele? Trudno, zebys tu zamieszczal caly swoj kod, ale
> moze sprobujesz powyzszego sposobu? Jesli do aktualizacji bazy nie uzywasz
> metod DAO, to i nie bedziesz mial bledow DAO w kolekcji DBEngine.Errors.
>
> Krzysztof Pozorek
>
>
Chciałbym wydobyć błąd powtórzenia w kluczu na formularzu opartym na tabeli
połączonej (odbc do MSSQL).Otrzymuje tylko błąd 3146 (Nieudane wywołanie ODBC).
**************************************************************
Zrobiłem wczoraj również próbę z tym co mi podesłałeś i otrzymałem ten sam błąd
(Nieudane wyw. odbc) (tylko jeden w kolekcji).Robiłem w ten sposób:
Dim errx As Error
Dim rst As DAO.Recordset
Dim db As Database
Dim i As Integer

Set db = OpenDatabase("SQL", False, False, "ODBC;DRIVER=SQL
Server;SERVER=SQLSRV1...)

Set rst = db.OpenRecordset("Select * from klienci", dbOpenDynaset)
rst.AddNew
rst("id") = 55
rst("nr") = 414124
rst("ex") = 0
rst("ed") = 0
rst.Update

Err_Polecenie18_Click:

If err <> 0 Then


For i = DBEngine.Errors.Count - 1 To 0 Step -1

Set errx = Errors(0)
msgbox errx.Description, 48
a = err.Number
Next i
End If
**************************************************************
Potem zrobiłem z taką obsługą (znalazłem to na grupie lub w helpie)
Err_Polecenie18_Click:
' Wylicz elementy kolekcji Errors i wyświetl
' właściwości każdego obiektu Error.
For Each errPętla In Errors
With errPętla
strblad = "Nr błędu: " & .Number & vbCr
strblad = strblad & _
" " & .Description & vbCr
strblad = strblad & _
" (Źródło: " & .Source & ")" & vbCr
strblad = strblad & _
"Naciśnij F1, aby obejrzeć " & _
"temat Pomocy " & .HelpContext & vbCr
strblad = strblad & _
" zamieszczony w pliku " & _
.HelpFile & "."

End With
msgbox strblad
Next

i to zwraca mi błąd 2627 - i to jest chyba błąd oznaczjący powtórzenie w
kluczu.
**************************************************************
Ale za nic nie mogę uzyskać tego na formularzu opartym na tabeli połączonej.

Rafał Posmyk

unread,
Oct 4, 2005, 4:11:39 AM10/4/05
to
Radek wrote at Montag, 3. Oktober 2005 11:50:

>> Mozesz przytoczyc kod, ktorym sprawdzasz bledy ?

> Oczywiście:
>
> Dim liczerr as integer

> [...]

Przecwiczylem to jeszcze raz i okazuje sie, ze uzywajac ADOBD
Zawsze otrzymuje tylko jeden blad w kolekcji - "ODBC - call failed".
Nie testowalem co bedzie w przypadku, jesli otworzymy jawnie polaczenie
do zrodla ODBC. W watku chodzi o obsluge bledu w formularzu wspopracujacym
z podlinkowana tabela - zatem DAO. Biblioteka DAO jest bardziej rozmowna.
Ponizsza peocedurka zwrwaca nastepujace bledy:

MSSQL:

Number : 3146
Description: ODBC--call failed.
Source : DAO.Recordset
-------
Number : 3621
Description: [Microsoft][ODBC SQL Server Driver][SQL Server]
Die Anweisung wurde beendet.
Source : ODBC.Recordset
-------
Number : 2601
Description: [Microsoft][ODBC SQL Server Driver][SQL Server]
Zeile mit doppeltem Schluessel kann in Objekt 'xxx'
mit eindeutigem Index 'xxx_PrimaryKey' nicht eingefuegt
werden.
Source : ODBC.Recordset

(nie chce mi sie tlumaczyc meldunkow :-) )

ORACLE

Number : 3146
Description: ODBC--call failed.
Source : DAO.Recordset
-------
Number : 1
Description: [Oracle][ODBC][Ora]ORA-00001: unique constraint
(xxx.SYS_C004045) violated
Source : ODBC.Recordset


W formularzu najlepiej zdefiniowac obsluge bledu dla calego formualarza
(OnError). Mozna takze zaryzykowac w BeforeUpdate ale nie jestem pewnien
czy bedzie dzialac.

Ciao, Smyk

PS: Oto kod, ktorego uzylem (DAO)
-----------------------------8<------------------------------------
Sub TestDAOErrorsCollection()

On Error GoTo TestDAOErrorsCollection_Error

Dim rs As DAO.Recordset
Dim e As DAO.Error

Set rs = DBEngine(0)(0).OpenRecordset("xxx", _
dbOpenDynaset, _
dbAppendOnly)

rs.AddNew
rs!xxx_Index = 8
rs.Update
rs.Close
Set rs = Nothing

TestDAOErrorsCollection_Exit:
Exit Sub

TestDAOErrorsCollection_Error:

Dim i&
'-- "For Each" takze dziala ale pokazuje bledy w odwrotnej kolej.
For i = Errors.Count - 1 To 0 Step -1
Set e = Errors(i)
With e
Debug.Print "Number : " & .Number
Debug.Print "Description: " & .Description
Debug.Print "Source : " & .Source
Debug.Print "-------"
End With
Next i
Set e = Nothing
Resume TestDAOErrorsCollection_Exit

End Sub

Rafał Posmyk

unread,
Oct 4, 2005, 4:27:30 AM10/4/05
to
Rafał Posmyk wrote at Dienstag, 4. Oktober 2005 10:11:

> W formularzu najlepiej zdefiniowac obsluge bledu dla calego formualarza
> (OnError).

Sprawdzilem - chodzi. Jako "Response" najlepiej zwrocic acDataErrContunue
i wyswietlich wlany medunek bledu (lub obsluzyc go inaczej).

Ciao, Smyk

Radek

unread,
Oct 4, 2005, 7:23:35 AM10/4/05
to

Tak, ale mnie intryguje dlaczego nie uzyskuję informacji o tych błedach mając
formularz oparty na kwerendzie i korzystając z metody zapisu w stylu:

DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70

Krzysztof Pozorek

unread,
Oct 4, 2005, 9:15:18 AM10/4/05
to
(...)

> Tak, ale mnie intryguje dlaczego nie uzyskuję informacji o tych błedach
> mając
> formularz oparty na kwerendzie i korzystając z metody zapisu w stylu:
>
> DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70

:-) No, nareszcie wyjawiles jak aktualizujesz te dane...

DBEngine.Errors dotyczy tylko bledow DAO. Twoja metoda DoCmd nie korzysta z
DAO, dlatego nie masz bledow w kolekcji.

K.P.

Rafał Posmyk

unread,
Oct 4, 2005, 9:30:23 AM10/4/05
to
Radek wrote at Dienstag, 4. Oktober 2005 13:23:

> Tak, ale mnie intryguje dlaczego nie uzyskuję informacji o tych błedach
> mając formularz oparty na kwerendzie i korzystając z metody zapisu w
> stylu:
>
> DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70

A sprawdziles co siedzi w Err ?
Pamietasz co bylo napisane w helpie o kasowaniu kolekcji w przypadku
wykonywania innych funkcji _mogacych_ sprowokowac blad ? Byc moze
zmiana kontekstu wykonywanej operacji (formularz -> makro -> formularz)
to wlasnie taka operacja ?

Radek

unread,
Oct 5, 2005, 5:47:56 AM10/5/05
to


Przerobiłem formularz żeby działał zgodnie ze sztuką (źródło danych jako
DAO.recordset) i działa ta obsługa błędów faktycznie. Formularz oparty na
kwerendzie to jednak ułomne rozwiazanie-nie udało mi się przy takim rozwiązaniu
wydobyć błędu powtórzenia w kluczu.


Dziękuje

0 new messages