ďťż
 
[ORACLE - dokumentacja] PL/SQL default EXCEPTION handler ďťż
 
[ORACLE - dokumentacja] PL/SQL default EXCEPTION handler
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

[ORACLE - dokumentacja] PL/SQL default EXCEPTION handler



=?iso-8859-2?Q?Piotr_Pli=BFga?= - 28-03-2006 00:02
[ORACLE - dokumentacja] PL/SQL default EXCEPTION handler
  Witam,
mam następujący problem. Tabela z jedną kolumną typu NUMBER(1)

Przypadek A)

1 SQL> INSERT INTO tabela VALUES(1);
2 SQL> INSERT INTO tabela VALUES('a');
3 SQL> COMMIT;

w wyniku błędu w drugiej lini Oracle wykona "statement-level rollback",
nastepnie COMMIT -> w tabeli znajdzie sie wiersz z lini 1 SQL> - dokładnie
liczva JEDEN.

Działa tak - jak się spodziewamy :-)

Przypadek B) - to samo tylko blok PL/SQL

BEGIN
INSERT INTO tabela VALUES(1);
INSERT INTO tabela VALUES('a');
COMMIT;
END;
/

Proszę zwrócić uwagę, że nie ma bloku EXCEPTION.

Zadanie
=======
Nie udało mi się znaleźć konstruktywnego wytłumaczenia w dokumentacji
ORACLE-a (SQL, PL/SQL, Conncept), że w tym przypadku nastąpi obsługa
błędu... no właśnie gdzie? Skoro nie ma bloku EXCEPTION?

Wiem, że nastąpi ROLLBACK i żaden z wierszy nie trafi do bazy danych, tylko
gdzie dokładnie to jest napisane?

W całym zadaniu chodzi o spór akademicki typu "prove it works like
designed"... i właściwie tylko o to... Gdyby był blok EXCEPTION i obsługa
wyjątku to nie ma sporu :-)

Pozdrawiam, Piotr

Pozdrawiam, Piotr Pliżga
--
Oracle Database Administrator
www.metrogroup.pl





dap - 28-03-2006 00:02

  Piotr Pliżga wrote:
> Witam,
> mam następujący problem. Tabela z jedną kolumną typu NUMBER(1)
>
> Przypadek A)
>
> 1 SQL> INSERT INTO tabela VALUES(1);
> 2 SQL> INSERT INTO tabela VALUES('a');
> 3 SQL> COMMIT;
>
> w wyniku błędu w drugiej lini Oracle wykona "statement-level rollback",
> nastepnie COMMIT -> w tabeli znajdzie sie wiersz z lini 1 SQL> - dokładnie
> liczva JEDEN.
>
> Działa tak - jak się spodziewamy :-)
>
> Przypadek B) - to samo tylko blok PL/SQL
>
> BEGIN
> INSERT INTO tabela VALUES(1);
> INSERT INTO tabela VALUES('a');
> COMMIT;
> END;
> /
>
> Proszę zwrócić uwagę, że nie ma bloku EXCEPTION.
>
> Zadanie
> =======
> Nie udało mi się znaleźć konstruktywnego wytłumaczenia w dokumentacji
> ORACLE-a (SQL, PL/SQL, Conncept), że w tym przypadku nastąpi obsługa
> błędu... no właśnie gdzie? Skoro nie ma bloku EXCEPTION?
>
> Wiem, że nastąpi ROLLBACK i żaden z wierszy nie trafi do bazy danych, tylko
> gdzie dokładnie to jest napisane?
>
> W całym zadaniu chodzi o spór akademicki typu "prove it works like
> designed"... i właściwie tylko o to... Gdyby był blok EXCEPTION i obsługa
> wyjątku to nie ma sporu :-)

Moze tak:
transaction

A logical unit of work that comprises one or more SQL statements
executed by a single user. According to the ANSI/ISO SQL standard, with
which Oracle is compatible, a transaction begins with the user's first
executable SQL statement. A transaction ends when it is explicitly
committed or rolled back by the user.

W 1 wypadku kazdy insert byl swoja wlasna transakcja, a w 2 transakcja
zaczela sie od begin a zakonczyla, wiec 1 insert nie zostal uznany.

> BEGIN
begin
INSERT INTO tabela VALUES(0);
end ;

> INSERT INTO tabela VALUES(1);
> INSERT INTO tabela VALUES('a');
> COMMIT;

begin
INSERT INTO tabela VALUES(3);
end ;

> END;
> /

wiecej tu
When an error occurs, an exception is raised. That is, normal execution
stops and control transfers to the exception-handling part of your
PL/SQL block or subprogram. Internal exceptions are raised implicitly
(automatically) by the run-time system. User-defined exceptions must be
raised explicitly by RAISE statements, which can also raise predefined
exceptions.

Wynika z tego,ze yyjatek jest zawsze robiony dla danego bloku (mozna
dodac tez savepointy), bo w razie bledu szuka jego obslugi w bloku
znajdujacym sie wyzej.

http://localhost/ora9i/appdev.920/a9..._errs.htm#1049

....ale ...

How Oracle Does Implicit Rollbacks

Before executing an INSERT, UPDATE, or DELETE statement, Oracle marks an
implicit savepoint (unavailable to you). If the statement fails, Oracle
rolls back to the savepoint. Normally, just the failed SQL statement is
rolled back, not the whole transaction. However, if the statement raises
an unhandled exception, the host environment determines what is rolled back.

If you exit a stored subprogram with an unhandled exception, PL/SQL does
not assign values to OUT parameters. Also, PL/SQL does not roll back
database work done by the subprogram.

http://localhost/ora9i/appdev.920/a9...6_ora.htm#1990




dap - 28-03-2006 00:02

  begin
begin
insert into test2 values(0) ;
-- commit ;
end ;

insert into test2 values(1) ;
insert into test2 values('a');
commit ;

begin
insert into test2 values(3) ;
commit ;
end ;

end ;
/

tu nie bedzie zadnego wpisu , bo w razi wyjatku caly wyjatek jest
propagowany wyzjej ( do innego bloku, albo programu).

begin
begin
insert into test2 values(0) ;
commit ;
end ;

insert into test2 values(1) ;
insert into test2 values('a');
commit ;

begin
insert into test2 values(3) ;
commit ;
end ;

end ;
/

to bedzie 0 bo commitem zaznaczylismy poczatek nowej transakcji.

Ja bym to tak rozumial...

dap




=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 28-03-2006 00:02

  Użytkownik Piotr Pliżga napisał:
> Witam,
> mam następujący problem. Tabela z jedną kolumną typu NUMBER(1)
>
> Przypadek A)
>
> 1 SQL> INSERT INTO tabela VALUES(1);
> 2 SQL> INSERT INTO tabela VALUES('a');
> 3 SQL> COMMIT;
>
> w wyniku błędu w drugiej lini Oracle wykona "statement-level rollback",
> nastepnie COMMIT -> w tabeli znajdzie sie wiersz z lini 1 SQL> - dokładnie
> liczva JEDEN.
>
> Działa tak - jak się spodziewamy :-)
>
> Przypadek B) - to samo tylko blok PL/SQL
>
> BEGIN
> INSERT INTO tabela VALUES(1);
> INSERT INTO tabela VALUES('a');
> COMMIT;
> END;
> /
>
> Proszę zwrócić uwagę, że nie ma bloku EXCEPTION.
>
> Zadanie
> =======
> Nie udało mi się znaleźć konstruktywnego wytłumaczenia w dokumentacji
> ORACLE-a (SQL, PL/SQL, Conncept), że w tym przypadku nastąpi obsługa
> błędu... no właśnie gdzie? Skoro nie ma bloku EXCEPTION?

W kliencie, którym tu pewnie jest SQL'plus, który wyswietlił wyjatek i czeka
na następne polecenia.

> Wiem, że nastąpi ROLLBACK i żaden z wierszy nie trafi do bazy danych, tylko
> gdzie dokładnie to jest napisane?

Nie nastąpi, jesli go nie wpiszesz. W tym drugim przypadku wciąż jestes w transakcji,
tyle że pustej (choć tego nie jestem pewien, a nie mam jak sprawdzić). Inaczej mówiąc
cofnięta nie została cała transakcja, a tylko ostatnia instrukcja (tu rozumiana
przez wszystko pomiedzy BEGIN END);

> W całym zadaniu chodzi o spór akademicki typu "prove it works like
> designed"... i właściwie tylko o to... Gdyby był blok EXCEPTION i obsługa
> wyjątku to nie ma sporu :-)

Żeby dowieść jak to działa, zrob insert przed blokiem a po bloku wykonaj commit. :)

--
P.M.





=?iso-8859-2?Q?Piotr_Pli=BFga?= - 28-03-2006 00:02

  Zwracam uwagę na fakt, że nie ma jawnie bloku EXCEPTION...

@dap - nie mogę się zgodzić z tym, że każdy SQL jest transakcją. Transakcja
kończy w tym przypadku z COMMIT - natomiast w drugiej linii wykonywany jest
"statement-level rollback". Natomiast co do bloku PL/SQL - gdybym dopisał
EXPCEPTION WHEN OTHERS THEN ROLLBACK to jest oczywiste, że kończy się
transakcja i następuje wycofanie (ROLLBACK) zmian niezatwierdzonych.
Natomiast tutaj nie mam nigdzie jawnego bloku EXCEPTION więc kto wskaże
miejsce w dokumentacji PL/SQL gdzie jest napisane, że "domyślny blok
EXCEPTION wykonuje ROLLBACK lub w przypadku błędu w bloku EXCEPTION jest
wykonywane ..."

Przychylam się do wytłumaczenia o propagacji wyjątków... Tak zresztą też
jest opisane w dokumentacji Oracle-a... No dobrze, ale nadal nie mamy
jawnej obsługi pt. EXCEPTION WHEN OTHERS THEN ROLLBACK;

Jeżeli nie mamy bloku PL/SQL to wytłumaczenie jest proste "statementp-level
rollback", następnie COMMIT, koniec transakcji, jeden wiersz w bazie.

@P.M - też jestem skłonny założyć, że blok PL/SQL traktowany jest jako
pojedynczy statment, więc działa to tak:
a) statement-level rollback w drugiej linii bloku PL/SQL;
b) błąd, więc -> propagacja wyjątku;
c) statement-level rollback "bloku" (jeżeli założyć, że blok to pojedynczy
statement);

Wiem jak działa, natomiast nadal brak dowodu... w postaci jawnego
wytłumaczenia w dokumentacji. Nie musi być w jednym rozdziale - może być
kilku aby było spójne.

Pozdrawiam, Piotr Pliżga
--
Oracle Database Administrator
www.metrogroup.pl




dap - 29-03-2006 00:26

  Dobrze sprobujmy inaczej:

Pytanie brzmi dlaczego w PL/SQL za pomoca programu SQLPLUS wyjatek w
anonimowym bloku powoduje wycofanie wszystkich transakcji z bloku.

1. Jak Oracle obługuje wyjatki - propaguje je dalej, do kolejnego bloku
albo do srodowiska(programu) w ktorym dana transakcja zotala wywolana.

http://localhost/ora9i/appdev.920/a9..._errs.htm#1193
Catching Unhandled Exceptions

Remember, if it cannot find a handler for a raised exception, PL/SQL
returns an unhandled exception error to the host environment, which
determines the outcome. For example, in the Oracle Precompilers
environment, any database changes made by a failed SQL statement or
PL/SQL block are rolled back.

2. W tym wypadku jest to SQLPLUS, a on traktuje caly blok PL/SQL jako
jedna transakcje, dlatego wystepuje standardowo wycofanie calego bloku.

http://localhost/ora9i/server.920/a9...13.htm#1012156

SET AUTO[COMMIT]{ON|OFF|IMM[EDIATE]|n}

Controls when Oracle commits pending changes to the database. ON commits
pending changes to the database after Oracle executes each successful
INSERT, UPDATE, or DELETE command or PL/SQL block. OFF suppresses
automatic committing so that you must commit changes manually (for
example, with the SQL command COMMIT). IMMEDIATE functions in the same
manner as the ON option. n commits pending changes to the database after
Oracle executes n successful SQL INSERT, UPDATE, or DELETE commands or
PL/SQL blocks. n cannot be less than zero or greater than 2,000,000,000.
The statement counter is reset to zero after successful completion of n
INSERT, UPDATE or DELETE commands or PL/SQL blocks, a commit, a
rollback, or a SET AUTOCOMMIT command.

!-> to jest chyba to co szukales <-!
Note:
For this feature, a PL/SQL block is considered one transaction,
regardless of the actual number of SQL commands contained within it.

dap




=?ISO-8859-2?Q?Witek_=A6wierzy?= - 02-04-2006 00:11

  dap wrote:
> Dobrze sprobujmy inaczej:
>
> Pytanie brzmi dlaczego w PL/SQL za pomoca programu SQLPLUS wyjatek w
> anonimowym bloku powoduje wycofanie wszystkich transakcji z bloku.
>
Nie spowoduje !
Np.:
begin
insert ...
commit;
insert_powodujacy_wyjatek;
commit;
end;
/
- pierwszy INSERT z bloku zostanie wprowadzony, drugi wycofany

>
> 1. Jak Oracle obługuje wyjatki - propaguje je dalej, do kolejnego bloku
> albo do srodowiska(programu) w ktorym dana transakcja zotala wywolana.
Gdy wyjatek _NIE_JEST_OBSLUGIWANY_ w danym bloku, to nastepuje
przerwanie wykonywania owego bloku i propagacja wyjatku do srodowiska
wolajacego.
Gdy wyjatek _JEST_OBSLUGIWANY_, to nastepuje przerwanie wykonania bloku,
wykonanie instrukcji w odp. bloku WHEN WYJATEK THEN i zakonczenie bloku
kodem = 0 (sukces) - w takiej sytuacji o wystapieniu wyjatku srodowisko
wolajace (czymkolwiek by nie bylo owo srodowisko wolajace - sql*plusem,
nadblokiem, czy czymkolwiek innym, co sobie mozesz wyobrazic )
>
> 2. W tym wypadku jest to SQLPLUS, a on traktuje caly blok PL/SQL jako
> jedna transakcje, dlatego wystepuje standardowo wycofanie calego bloku.
>
> http://localhost/ora9i/server.920/a9...13.htm#1012156
>
transakcja, a blok plsql to sa dwie _ZUPELNIE_ _ROZNE_ sprawy, nijak sie
majace do siebie. Gdy w bloku PLSQL nie ma commita, to transakcja
_NIE_ZOSTANIE_ZATWIERDZONA_
pozdrawiam
Witek Swierzy
wswier@sgh.waw.pl




dap - 04-04-2006 00:08

  Witek Świerzy wrote:
> dap wrote:
>
>> Dobrze sprobujmy inaczej:
>>
>> Pytanie brzmi dlaczego w PL/SQL za pomoca programu SQLPLUS wyjatek w
>> anonimowym bloku powoduje wycofanie wszystkich transakcji z bloku.
>>
> Nie spowoduje !
> Np.:
> begin
> insert ...
> commit;
> insert_powodujacy_wyjatek;
> commit;
> end;
> /
> - pierwszy INSERT z bloku zostanie wprowadzony, drugi wycofany

Jasne
Po commit transakcja jest zakonczona i de facto nie jest juz transakcja,
wiec tym bardziej nie mozna jej wycofac, ale mozna wycofac wszystkie
inne rozpoczete transakcje i o tym pisalem. W poscie powyzej cytowalem
opis dzialania implicite rollback.

>>
>> 1. Jak Oracle obługuje wyjatki - propaguje je dalej, do kolejnego
>> bloku albo do srodowiska(programu) w ktorym dana transakcja zotala
>> wywolana.
>
> Gdy wyjatek _NIE_JEST_OBSLUGIWANY_ w danym bloku, to nastepuje
> przerwanie wykonywania owego bloku i propagacja wyjatku do srodowiska
> wolajacego.
> Gdy wyjatek _JEST_OBSLUGIWANY_, to nastepuje przerwanie wykonania bloku,
> wykonanie instrukcji w odp. bloku WHEN WYJATEK THEN i zakonczenie bloku
> kodem = 0 (sukces) - w takiej sytuacji o wystapieniu wyjatku srodowisko
> wolajace (czymkolwiek by nie bylo owo srodowisko wolajace - sql*plusem,
> nadblokiem, czy czymkolwiek innym, co sobie mozesz wyobrazic )

Chyba nie do konca - opisywalem sytuacje gdy wyjatek nie jest
obslugiwany besposrednio w tym samym bloku - tak jak w pytaniu.
Wyjatek zawsze jest propagowny wyzej, nie ma bezposredniego wyskoczenie
z bardzo zagniezdzonego bloku bezposrednio do srodowiska wywolujacego
- no chyba, ze jako srodowisko wywolujace rozumiesz inny blok (tak
przynajmniej jest w 10g - popatrz na kod ponizej).

Popatrz tu - wyjatek jest propagowany do kazdego bloku wyzej - zaden z
blokow go nie obsluguje i dlatego konczy sie on w SQLPLUSIE.

23:20:39 SQL> begin
begin
insert into test2 values(0) ;
begin
insert into test2 values('a');
end ;
commit ;
end ;

insert into test2 values(1) ;
commit ;

begin
insert into test2 values(3) ;
commit ;
end ;

end ;
/ 23:20:40 2 23:20:40 3 23:20:40 4 23:20:40 5 23:20:40
6 23:20:40 7 23:20:40 8 23:20:40 9 23:20:40 10 23:20:40 11
23:20:40 12 23:20:40 13 23:20:40 14 23:20:40 15 23:20:40 16
23:20:40 17 23:20:40 18 23:20:40 19
begin
*
ERROR at line 1:
ORA-01722: invalid number
ORA-06512: at line 5

Elapsed: 00:00:00.00
23:20:40 SQL> select * from test2 ;

no rows selected

Tu natomiast wyjatek jest obslugiwany w bloku o 1 wyzej, gdyby pojawialo
sie wyjscie bezposrednio do SQLPLUS to bylo by 3 insertow.

23:24:18 SQL> begin
begin
insert into test2 values(0) ;
begin
insert into test2 values('a');
end ;
commit ;
exception when others then
null ;
end ;

insert into test2 values(1) ;
commit ;

begin
insert into test2 values(3) ;
commit ;
end ;

end ;
/
23:24:20 2 23:24:20 3 23:24:20 4 23:24:20 5 23:24:20 6
23:24:20 7 23:24:20 8 23:24:20 9 23:24:20 10 23:24:20 11
23:24:20 12 23:24:20 13 23:24:20 14 23:24:20 15 23:24:20 16
23:24:20 17 23:24:20 18 23:24:20 19 23:24:20 20 23:24:20 21
PL/SQL procedure successfully completed.

Elapsed: 00:00:00.16
23:24:20 SQL> select * from test2 ;

A
----------
0
1
3

Elapsed: 00:00:00.00
23:24:25 SQL>

>> 2. W tym wypadku jest to SQLPLUS, a on traktuje caly blok PL/SQL jako
>> jedna transakcje, dlatego wystepuje standardowo wycofanie calego bloku.
>>
>> http://localhost/ora9i/server.920/a9...13.htm#1012156
>>
> transakcja, a blok plsql to sa dwie _ZUPELNIE_ _ROZNE_ sprawy, nijak sie
> majace do siebie. Gdy w bloku PLSQL nie ma commita, to transakcja
> _NIE_ZOSTANIE_ZATWIERDZONA_

Wlasnie wyglada, ze dla SQLPLUS z anonimowym blokiem jest inaczej blok
PL/SQL = transakcja - i stad pytanie pytanie PP, gdzie w dokumentacji
Oracle mozna znalezc, ze bylo to zamierzone dzialanie.

Ponizej kod pokazuje insert do bazy danych w bloku PL/SQL bez
zatwierdzenia, (dokladnie tak samo jak w wypadku zwyklego SQL).

SQL>
SQL> select * from test2 ;
SP2-0640: Not connected
SQL> conn / as sysdba
Connected.
SQL> select * from test2 ;

no rows selected

SQL> begin
begin
insert into test2 values(0) ;
end ;

insert into test2 values(1) ;

begin
insert into test2 values(3) ;
end ;

end ;
/ 2 3 4 5 6 7 8 9 10 11 12 13 14

PL/SQL procedure successfully completed.

SQL> select * from test2;

A
----------
0
1
3

SQL> disc
Disconnected from Oracle Database 10g Express Edition Release 10.2.0.1.0
- Production
SQL> conn / as sysdba
Connected.
SQL> select * from test2 ;

A
----------
0
1
3

SQL>

Pozdrawiam
dap
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    Oracle 19g +Insert +Insert +Insert... [oracle] zapytanie dynamiczne z =?ISO-8859-2?Q?=22dynamiczn=B1_?==?ISO-8859-2?Q?nazw=B1_tabeli=22?= [Oracle] jak =?ISO-8859-2?Q?ograniczy=E6_pami=EA=E6_dla_se?==?ISO-8859-2?Q?rwera=3F?= =?ISO-8859-2?Q?=5BOT=5D_Zdany_egzamin_Oracle_1Z0-007_a?==?ISO-8859-2?Q?_brak_informacji_na_stronie_Prometric_-_czy?==?ISO-8859-2?Q?_co=B6_nie_tak=3F?= jak to =?ISO-8859-2?Q?zrobi=E6=2E=2E=2E=3F_TSQL_sql_server?==?ISO-8859-2?Q?_?= [oracle] czy da =?ISO-8859-2?Q?si=EA_z_poziomu_procedury_?==?ISO-8859-2?Q?zrobi=E6_kopi=EA_zapasow=B1=3F?= [oracle 10g] czy =?ISO-8859-2?Q?mo=BFna_wy=B3=B1czy=E6_wszys?==?ISO-8859-2?Q?tkie_wi=EAzy_w_schemacie=3F?= MSSQL Express czy Oracle Express =?iso-8859-2?q?[oracle]_Jak_sprawdzi=E6_wielko=B6=E6_tabeli_=3F=3F?= =?ISO-8859-2?Q?Poszukjue_ksi=B1=BFki_"Oracle_?= =?ISO-8859-2?Q?optymalizacja_wydajno=B6ci"..?=
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • felgiuzywane.xlx.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com