sql >> Database >  >> RDS >> Oracle

Slash of geen Slash?

Dat is de vraag.

Een recent bericht op de OTN-forums vroeg naar het gebruik van puntkomma's en schuine strepen als terminators van uitspraken. Ik heb een artikel over dit onderwerp dat ik meer dan 4 jaar geleden voor ons ontwikkelingsteam schreef, afgestoft. Dit artikel kreeg goede recensies en is desgewenst beschikbaar op de OTN-forums. Ik dacht ik zet het ook op mijn blog. Hier is het artikel:

Slash of geen slash

door Brian Peasland

Bij ons bedrijf worden SQL-scripts die worden geïmplementeerd, uitgevoerd in Oracle's SQL*Plus-opdrachtregelhulpprogramma, terwijl veel ontwikkelaars een GUI-tool gebruiken zoals PL/SQL Developer of SQL Developer. De schuine streep betekent iets voor SQL*Plus dat niet nodig is in PL/SQL Developer of SQL Developer. Als zodanig kan het verwarrend zijn om te weten of u een slash in uw SQL-scripts moet opnemen of niet. Hopelijk zal dit gedeelte enig licht werpen op wat de schuine streep doet, wanneer het te gebruiken en wanneer het niet te gebruiken. Puntkomma Terminator Voor de meeste SQL-instructies is de puntkomma de terminator van de instructie. Beschouw bijvoorbeeld deze eenvoudige SQL-instructie die wordt uitgevoerd in SQL*Plus:

SQL> selecteer sysdate van dual;

SYSDATUM

———

18-JUN-12

Wanneer SQL*Plus de puntkomma ziet, weet het dat het einde van de SQL-instructie is bereikt en kan het de opdracht nu uitvoeren.

SQL*Plus-buffer

U weet misschien niet dat SQL*Plus een buffer heeft voor zijn opdrachten. Als ik op de 'l'-toets voor 'lijst' druk, kan ik de opdracht zien die zich momenteel in de buffer van mijn sessie bevindt.

SQL> l

1* selecteer sysdate van dual

Het is niet verrassend dat er de opdracht is die ik zojuist heb uitgevoerd. Ik heb toen nog een SQL-statement uitgevoerd en zo ziet mijn buffer er nu uit:

SQL> l

1 selecteer sysdate,gebruiker

2* vanaf dubbel

Zoals je kunt zien, heb ik nu twee regels in de SQL*Plus-buffer van mijn sessie.

Slash =Buffer uitvoeren

De eerste regel die u over de slash moet begrijpen, is dat voor SQL*Plus de slash betekent dat de inhoud van de buffer wordt uitgevoerd. Om dit concept te illustreren, zal ik een SQL-instructie uitvoeren, een paar seconden wachten en dan dezelfde SQL-instructie opnieuw uitvoeren, maar alleen de buffer uitvoeren.

SQL> selecteer to_char(sysdate,'MM/DD/YYYY HH24:MI:SS') van dual;

TO_CHAR(SYSDATE,'MM

——————-

18/06/2012 15:20:40

SQL> /
TO_CHAR(SYSDATE,’MM

——————-

18/06/2012 15:21:17

SQL> /

TO_CHAR(SYSDATE,'MM

——————-

18/06/2012 15:21:50

Je kunt zien dat alles wat ik deed de tweede en derde keer was om gewoon '/' te typen en op enter te drukken en SQL*Plus voerde elke keer de inhoud van de opdrachtbuffer uit.

PL/SQL-blokken

De terminator van de puntkomma-statements werkte op zichzelf prima totdat Oracle PL/SQL introduceerde in Oracle versie 7. Het probleem is dat PL/SQL-blokken meerdere puntkomma's kunnen hebben om de afzonderlijke instructies waaruit dat blok bestaat te beëindigen. Overweeg dit zeer eenvoudige PL/SQL-blok dat niets doet:

SQL> begin

2 null;

3 null;

4 einde;

5

Regels 2 en 3 bevatten volkomen geldige uitspraken die elk worden afgesloten met een puntkomma. En in regel 4 hebben we het END-sleutelwoord dat het einde van het PL/SQL-blok aangeeft. Als we geneste BEGIN/END-paren niet mochten toestaan, dan ziet SQL*Plus telkens "END;" het zou weten dat het einde van het PL/SQL-blok is bereikt, maar we mogen geneste BEGIN/END-paren gebruiken, dus het volgende is volkomen legaal en geldig:

SQL> begin

2 begin

3 null;

4 einde;

5 null;

6 einde;

7

U kunt aan het bovenstaande zien dat u alleen maar op zoek bent naar "END;" is niet genoeg omdat SQL*Plus zou hebben geprobeerd het blok na regel 4 uit te voeren. Dus hoe besloot Oracle om aan te geven dat het PL/SQL-blok gereed was om uitgevoerd te worden? Het antwoord is door de slash te gebruiken, zoals je misschien al weet. De tweede regel die u moet begrijpen, is dat alle slash die u gebruikt om een ​​PL/SQL-blok te beëindigen, is om SQL*Plus te vertellen om uit te voeren wat zich in de buffer bevindt! Dit is niet veranderd sinds voordat PL/SQL voor Oracle 7 werd gemaakt. Bekijk het volgende voorbeeld:

SQL> begin

2 null;

3 einde;

4 /

PL/SQL-procedure succesvol afgerond.

SQL> l

1 begin
2 null;

3* einde;

Op regel 4 typte ik de schuine streep om het PL/SQL-blok uit te voeren. Je kunt zien dat mijn blok succesvol is voltooid. Als we teruggaan en naar de inhoud van mijn commandobuffer kijken, kun je zien dat het alles bevat behalve de schuine streep. De slash maakt geen deel uit van de opdrachtbuffer. Dus nu zal ik een ander PL/SQL-blok uitvoeren:

SQL> begin

2 dbms_output.put_line(‘Vandaag is het ‘||to_char(sysdate,’MM/DD/YYYY HH24:MI:SS’));

3 einde;

4 /

Het is vandaag 18/06/2012 15:39:32

PL/SQL-procedure succesvol afgerond.

De schuine streep zei tegen SQL*Plus om uit te voeren wat zich in de buffer bevindt, en de resultaten worden weergegeven. Laten we nu opnieuw de schuine streep typen en we zouden moeten zien dat ons PL/SQL-blok opnieuw wordt uitgevoerd.

SQL> /

Het is vandaag 18-06-2012 15:40:42

PL/SQL-procedure succesvol afgerond.

Ik hoefde mijn PL/SQL-blok niet opnieuw te typen omdat het zich momenteel in de commandobuffer bevindt.

PL/SQL- en SQL-ontwikkelaar en PL/SQL-blokken

Het grootste probleem voor de meeste ontwikkelaars is dat u voor PL/SQL Developer en SQL Developer geen slash hoeft te gebruiken. Waarom? Omdat je op Execute (F8) of Run Script (F5) kunt drukken om je PL/SQL-blok uit te voeren. De PL/SQL-ontwikkelaar weet dat op het moment dat u op F8 drukt, u van plan bent het PL/SQL-blok in te dienen om uit te voeren. In dit geval doet F8 in PL/SQL Developer hetzelfde werk als de schuine streep in SQL*Plus. Zo ook voor F5 in SQL Developer.

Het probleem bij mijn bedrijf is dat ons team dat code implementeert in productie geen code implementeert met PL/SQL Developer of SQL Developer. Ze gebruiken SQL*Plus omdat het scripten van meerdere uitvoeringen eenvoudiger is met een opdrachtregelprogramma. Veel ontwikkelaars maken de fout om de slash voor PL/SQL-blokken niet in scripts op te nemen omdat ze deze niet nodig hebben, maar als je die codesectie in een SQL-script wilt implementeren, is de slash vereist aan het einde van elke PL /SQL-blok.

Wanneer geen slash gebruiken

Dus we hebben gezien wanneer en waarom we de slash gebruiken, maar wanneer is het slecht om het te gebruiken? De derde regel die u moet weten, is dat het slecht is om de slash na een enkele SQL-instructie (niet in een PL/SQL-blok) te gebruiken, vooral wanneer die slash onmiddellijk volgt op een DML-instructie (INSERT, UPDATE of DELETE). Als mijn script het volgende bevat:

selecteer sysdate van dual;

/

Dan krijg ik "dubbele uitvoer", wat ik normaal niet van plan ben in een script. Ik wil eigenlijk maar één regel teruggeven, niet twee zoals het bovenstaande script zou doen:

SQL> selecteer sysdate van dual;

SYSDATUM

———

18-JUN-12
SQL> /

SYSDATUM

———

18-JUN-12

Het is nog erger als ik de slash na een DML-instructie gebruik, omdat die instructie twee keer wordt uitgevoerd. Overweeg het volgende script:

invoegen in test_tab-waarden (10);

/

We weten nu dat wanneer ik de twee regels hierboven in een script uitvoer, SQL*Plus het één keer zal uitvoeren vanwege de terminator van de puntkomma-instructie en dan een tweede keer zal uitvoeren omdat de slash SQL*Plus vertelt om uit te voeren wat in de commando buffer. Als ik het bovenstaande tweeregelige script uitvoer, krijg ik de volgende uitvoer:

SQL> invoegen in test_tab-waarden (10);

1 rij gemaakt.

SQL>

/

invoegen in test_tab-waarden (10) *

FOUT op regel 1:ORA-00001:unieke beperking (PEASLAND.SYS_C00767176) geschonden

Oeps! De eerste invoeging werkte (1 rij gemaakt.) Maar toen de slash werd ingevoerd, probeerde SQL*Plus dezelfde gegevens in te voegen en werd ik betrapt op een unieke schending van de beperking.

Conclusie

Hopelijk laat deze pagina zien waarom de schuine streep nodig is, wat het doet en wanneer het niet moet worden gebruikt. Om samen te vatten:

  • Voeg de slash toe aan het einde van elk PL/SQL-blok
  • Voeg geen slash toe na SQL-instructies die niet in een PL/SQL-blok staan.
  • De slash na een enkele SQL-instructie zorgt ervoor dat die SQL-opdracht twee keer wordt uitgevoerd.

  1. slaapstand kan de volgende reekswaarde niet krijgen

  2. Hoe UNCOMPRESSED_LENGTH() werkt in MariaDB

  3. Maak een index op een enorme MySQL-productietafel zonder tafelvergrendeling

  4. Toegang geweigerd voor gebruiker 'root'@'localhost' (met wachtwoord:JA) - Geen rechten?