Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Ukośnik czy nie ukośnik?

Oto jest pytanie.

Niedawny post na forach OTN pytał o używanie średników i ukośników jako terminatorów instrukcji. Odkurzyłem artykuł, który napisałem dla naszego zespołu programistów ponad 4 lata temu na ten temat. Ten artykuł otrzymał dobre recenzje i jest dostępny na forach OTN w razie potrzeby. Pomyślałem, że opublikuję to również na moim blogu. Oto artykuł:

Ukośnik lub bez ukośnika

autorstwa Briana Peaslanda

W naszej firmie skrypty SQL, które są wdrażane, są wykonywane w narzędziu wiersza poleceń Oracle SQL*Plus, podczas gdy wielu programistów korzysta z narzędzi GUI, takich jak PL/SQL Developer lub SQL Developer. Ukośnik oznacza dla SQL*Plus coś, co nie jest potrzebne w PL/SQL Developer lub SQL Developer. W związku z tym wiedza o tym, czy w skryptach SQL musisz zawierać ukośnik, może być myląca. Mamy nadzieję, że ta sekcja rzuci trochę światła na to, co robi ukośnik, kiedy go używać, a kiedy nie. Terminator średnika W przypadku większości instrukcji SQL średnik jest terminatorem instrukcji. Rozważmy na przykład tę prostą instrukcję SQL uruchomioną w SQL*Plus:

SQL> wybierz sysdate z dual;

SYSDATE

———

18-CZE-12

Kiedy SQL*Plus widzi średnik, wie, że osiągnięto koniec instrukcji SQL i może teraz wykonać polecenie.

Bufor SQL*Plus

Możesz nie wiedzieć, że SQL*Plus ma bufor dla swoich poleceń. Jeśli nacisnę klawisz „l” dla „listy”, zobaczę polecenie aktualnie w buforze mojej sesji.

SQL> l

1* wybierz sysdate z podwójnego

Nic dziwnego, że właśnie wykonałem polecenie. Następnie wykonałem kolejną instrukcję SQL i oto jak teraz wygląda mój bufor:

SQL> l

1 wybierz datę systemową, użytkownik

2* od podwójnego

Jak widać, mam teraz dwie linie w buforze SQL*Plus mojej sesji.

Ukośnik =Wykonaj bufor

Pierwszą zasadą, którą należy zrozumieć o ukośniku, jest to, że dla SQL*Plus ukośnik oznacza wykonanie zawartości bufora. Aby zilustrować tę koncepcję, wykonam instrukcję SQL, poczekam kilka sekund, a następnie ponownie wykonam tę samą instrukcję SQL, ale tylko wykonam bufor.

SQL> wybierz to_char(sysdate,’MM/DD/RRRR HH24:MI:SS’) z dual;

TO_CHAR(SYSDATE,’MM

)

——————-

18.06.2012 15:20:40

SQL> /
TO_ZNAK(SYSDATE;'MM

)

——————-

18.06.2012 15:21:17

SQL> /

TO_CHAR(SYSDATE,’MM

)

——————-

18.06.2012 15:21:50

Widać, że wszystko, co zrobiłem drugi i trzeci raz, to po prostu wpisanie „/” i naciśnięcie enter, a SQL*Plus za każdym razem wykonał zawartość swojego bufora poleceń.

Bloki PL/SQL

Terminator instrukcji średnika działał sam, dopóki Oracle nie wprowadziło PL/SQL w wersji Oracle 7. Problem polega na tym, że bloki PL/SQL mogą mieć wiele średników, aby zakończyć poszczególne instrukcje, które tworzą ten blok. Rozważ ten bardzo prosty blok PL/SQL, który nic nie robi:

SQL>rozpocznij

2 brak;

3 brak;

4 koniec;

5

Wiersze 2 i 3 zawierają całkowicie poprawne instrukcje, z których każda jest zakończona średnikiem. W wierszu 4 mamy słowo kluczowe END oznaczające koniec bloku PL/SQL. Jeśli nie wolno nam było zagnieżdżać par BEGIN/END, to za każdym razem SQL*Plus widzi „END;” wiedziałby, że osiągnięto koniec bloku PL/SQL, ale wolno nam zagnieżdżać pary BEGIN/END, więc poniższe jest całkowicie legalne i poprawne:

SQL>rozpocznij

2 początek

3 brak;

4 koniec;

5 brak;

6 koniec;

7

Z powyższego można wywnioskować, że po prostu szukam „KONIEC”; to za mało, ponieważ SQL*Plus próbowałby uruchomić blok po wierszu 4. Jak więc firma Oracle zdecydowała się oznaczyć, że blok PL/SQL jest gotowy do wykonania? Odpowiedzią jest użycie prawego ukośnika, o czym być może już wiesz. Drugą zasadą, którą należy zrozumieć, jest to, że ukośnik używany do zakończenia bloku PL/SQL polega na tym, aby nakazać SQL*Plus uruchomienie tego, co znajduje się w buforze! Nie zmieniło się to od czasu utworzenia PL/SQL dla Oracle 7. Rozważmy następujący przykład:

SQL>rozpocznij

2 brak;

3 koniec;

4 /

Procedura PL/SQL zakończona pomyślnie.

SQL> l

1 początek
2 null;

3* koniec;

W wierszu 4 wpisałem ukośnik, aby wykonać blok PL/SQL. Widać, że mój blok został pomyślnie zakończony. Jeśli cofniemy się i spojrzymy na zawartość mojego bufora poleceń, zobaczysz, że zawiera on wszystko oprócz ukośnika. Ukośnik nie jest częścią bufora poleceń. Więc teraz uruchomię inny blok PL/SQL:

SQL>rozpocznij

2 dbms_output.put_line('Dzisiaj jest'||to_char(sysdate,'MM/DD/RRRR HH24:MI:SS'));

3 koniec;

4 /

Dzisiaj jest 18.06.2012 15:39:32

Procedura PL/SQL zakończona pomyślnie.

Ukośnik mówi do SQL*Plus, aby uruchomił zawartość bufora, a wyniki są wyświetlane. Teraz wpiszmy ponownie tylko ukośnik i powinniśmy zobaczyć, jak nasz blok PL/SQL zostanie ponownie wykonany.

SQL> /

Dzisiaj jest 18.06.2012 15:40:42

Procedura PL/SQL zakończona pomyślnie.

Nie musiałem wpisywać mojego bloku PL/SQL od nowa, ponieważ znajduje się on obecnie w buforze poleceń.

PL/SQL i SQL Developer oraz bloki PL/SQL

Największym problemem większości programistów jest to, że PL/SQL Developer i SQL Developer nie wymagają używania ukośnika. Czemu? Ponieważ możesz nacisnąć Wykonaj (F8) lub Uruchom skrypt (F5), aby uruchomić swój blok PL/SQL. Programista PL/SQL wie, że w momencie naciśnięcia klawisza F8 zamierzasz przesłać blok PL/SQL do wykonania. W tym przypadku klawisz F8 w PL/SQL Developer wykonuje to samo zadanie, co ukośnik w SQL*Plus. Podobnie dla F5 w SQL Developer.

Problem w mojej firmie polega na tym, że nasz zespół wdrażający kod do produkcji nie wdraża kodu za pomocą PL/SQL Developer lub SQL Developer. Używają SQL*Plus, ponieważ skrypty wielu wykonań są łatwiejsze dzięki narzędziu wiersza poleceń. Wielu programistów popełnia błąd polegający na nieuwzględnianiu ukośnika dla bloków PL/SQL w skryptach, ponieważ go nie potrzebują, ale jeśli chcesz wdrożyć tę sekcję kodu w skrypcie SQL, ukośnik jest wymagany na końcu każdego PL Blok /SQL.

Kiedy nie używać ukośnika

Widzieliśmy więc, kiedy i dlaczego używamy ukośnika, ale kiedy jest źle go używać? Trzecią zasadą, o której trzeba wiedzieć, jest to, że używanie ukośnika następującego po pojedynczej instrukcji SQL (nie w bloku PL/SQL) jest złe, zwłaszcza gdy ten ukośnik następuje bezpośrednio po instrukcji DML (INSERT, UPDATE lub DELETE). Jeśli mój skrypt zawiera następujące elementy:

wybierz sysdate z dual;

/

Wtedy otrzymam „podwójne wyjście”, co nie jest tym, co normalnie zamierzam robić w skrypcie. Naprawdę chcę zwrócić tylko jedną linię, a nie dwie, jak zrobiłby powyższy skrypt:

SQL> wybierz sysdate z dual;

SYSDATE

———

18-CZE-12
SQL> /

SYSDATE

———

18-CZE-12

Jeszcze gorzej jest, gdy używam ukośnika następującego po instrukcji DML, ponieważ ta instrukcja zostanie wykonana dwukrotnie. Rozważ następujący skrypt:

wstaw do test_tab wartości (10);

/

Teraz wiemy, że kiedy wykonuję dwie powyższe linie w skrypcie, SQL*Plus wykona je raz ze względu na terminator instrukcji średnika, a następnie wykona drugi raz, ponieważ ukośnik mówi SQL*Plus, aby uruchomić to, co jest w bufor poleceń. Kiedy wykonuję powyższy dwuwierszowy skrypt, otrzymuję następujące dane wyjściowe:

SQL> wstawiamy do test_tab wartości (10);

Utworzono 1 wiersz.

SQL>

/

wstaw do test_tab wartości (10) *

BŁĄD w wierszu 1:ORA-00001:naruszone ograniczenie unikatowe (PEASLAND.SYS_C00767176)

Ups! Pierwsze wstawienie zadziałało (utworzono 1 wiersz), ale kiedy wprowadzono ukośnik, SQL*Plus próbował wstawić te same dane i zostałem złapany na naruszeniu unikatowego ograniczenia.

Wniosek

Mamy nadzieję, że ta strona pokazuje, dlaczego ukośnik jest potrzebny, co robi i kiedy go nie używać. Podsumowując:

  • Dołącz ukośnik na końcu każdego bloku PL/SQL
  • Nie dołączaj ukośnika po żadnych instrukcjach SQL spoza bloku PL/SQL.
  • Ukośnik po pojedynczej instrukcji SQL spowoduje dwukrotne wykonanie tego polecenia SQL.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wybrać pierwszą 1 i uporządkowaną według daty w Oracle SQL?

  2. oracle sql:zaktualizuj, jeśli istnieje, wstawiaj jeszcze

  3. Formatowanie ciągu UUID bez REGEXP_REPLACE i PL/SQL

  4. zmień tabelę modyfikuj kolumnę w bazie danych Oracle

  5. UPPER() Funkcja w Oracle