Dynamic SQL is een programmeertechniek waarmee u SQL statements dynamisch kunt bouwen tijdens runtime. U kunt meer algemene, flexibele toepassingen maken met behulp van dynamische SQL omdat de volledige tekst van een SQL-statement onbekend kan zijn bij het compileren. Met dynamic SQL kunt u bijvoorbeeld een procedure maken die werkt op een tabel waarvan de naam tot runtime niet bekend is.,
Oracle bevat twee manieren om dynamische SQL te implementeren in een PL/SQL-toepassing:
- Native dynamic SQL, waarbij u dynamische SQL-statements rechtstreeks in PL / SQL-blokken plaatst.
- Aanroepprocedures in het
DBMS_SQL
pakket.
Dit hoofdstuk behandelt de volgende onderwerpen:
- “Wat Is dynamische SQL?”
- ” waarom dynamische SQL gebruiken?,”
- ” een dynamisch SQL-Scenario met Native Dynamic SQL “
- ” kiezen tussen Native Dynamic SQL en het Dbms_sql-pakket “
- ” dynamische SQL gebruiken in andere talen dan PL/SQL “
- ” PL/SQL-Records gebruiken in SQL INSERT and UPDATE Statements”
u kunt details vinden over de DBMS_SQL
pakket in de Oracle9i geleverde PL/SQL pakketten en types referentie.
Wat Is dynamische SQL?
Dynamic SQL stelt u in staat om programma ‘ s te schrijven die verwijzen naar SQL-statements waarvan de volledige tekst niet bekend is tot runtime., Alvorens dynamische SQL in detail te bespreken, kan een duidelijke definitie van statische SQL een goed uitgangspunt zijn voor het begrijpen van dynamische SQL. Statische SQL-statements veranderen niet van uitvoering naar uitvoering. De volledige tekst van statische SQL-statements is bekend bij de compilatie, wat de volgende voordelen biedt:
- succesvolle compilatie controleert of de SQL-statements verwijzen naar geldige databaseobjecten.
- succesvolle compilatie controleert of de benodigde rechten aanwezig zijn om toegang te krijgen tot de database-objecten.,
- de prestaties van statische SQL zijn over het algemeen beter dan dynamische SQL.
vanwege deze voordelen moet u dynamische SQL alleen gebruiken als u geen statische SQL kunt gebruiken om uw doelen te bereiken, of als het gebruik van statische SQL omslachtig is in vergelijking met dynamische SQL. Statische SQL heeft echter beperkingen die kunnen worden overwonnen met dynamische SQL. U kent misschien niet altijd de volledige tekst van de SQL statements die uitgevoerd moeten worden in een PL/SQL procedure., Uw programma kan gebruikersinvoer accepteren die de uit te voeren SQL-statements definieert, of uw programma moet mogelijk wat verwerkingswerk voltooien om de juiste koers te bepalen. In dergelijke gevallen moet u dynamische SQL gebruiken.
bijvoorbeeld, een reporting applicatie in een data warehouse omgeving kan de exacte tabelnaam niet kennen tot runtime., Deze tabellen kunnen worden genoemd volgens de beginmaand en het jaar van het kwartaal, bijvoorbeeld INV_01_1997
, INV_04_1997
, INV_07_1997
, INV_10_1997
, INV_01_1998
, en zo verder. U kunt dynamic SQL gebruiken in uw rapportagetoepassing om de tabelnaam tijdens runtime op te geven.
u kunt ook een complexe query uitvoeren met een door de gebruiker te selecteren sorteervolgorde., In plaats van de query tweemaal te coderen, met verschillende ORDER BY
clausules, kunt u de query dynamisch construeren om een opgegeven ORDER BY
clausule op te nemen.
dynamische SQL-programma ‘ s kunnen veranderingen in gegevensdefinities verwerken, zonder de noodzaak om opnieuw te compileren. Dit maakt dynamische SQL veel flexibeler dan statische SQL. Met Dynamic SQL kunt u herbruikbare code schrijven, omdat de SQL gemakkelijk kan worden aangepast aan verschillende omgevingen..,met
Dynamic sql kunt u ook DDL-statements (data definition language) en andere SQL-statements uitvoeren die niet worden ondersteund in puur statische SQL-programma ‘ s.
waarom dynamische SQL gebruiken?
u moet dynamische SQL gebruiken in gevallen waarin statische SQL de operatie die u wilt uitvoeren niet ondersteunt, of in gevallen waarin u niet precies weet welke SQL-statements moeten worden uitgevoerd door een PL/SQL-procedure. Deze SQL statements kunnen afhangen van de input van de gebruiker, of ze kunnen afhangen van het verwerken van werk gedaan door het programma.,DL and SCL Statements in PL/SQL
In PL/SQL, you can only execute the following types of statements using dynamic SQL, rather than static SQL:
- Data definition language (DDL) statements, such as
CREATE
,DROP
,GRANT
, andREVOKE
- Session control language (SCL) statements, such as
ALTER
SESSION
andSET
ROLE
See Also:Oracle9i SQL Reference for information about DDL and SCL statements.,
ook kunt u alleen de TABLE
clausule gebruiken in de SELECT
statement via dynamische SQL. Het volgende PL/SQL-blok bevat bijvoorbeeld eenSELECT
statement dat deTABLE
– clausule gebruikt en native dynamische SQL:
dynamische query ’s uitvoeren
u kunt dynamische SQL gebruiken om toepassingen te maken die dynamische query’ s uitvoeren, waarvan de volledige tekst niet bekend is tot runtime., Veel soorten toepassingen moeten dynamische query ‘ s gebruiken, waaronder:
- toepassingen die gebruikers toestaan om query-zoek-of sorteercriteria in runtime in te voeren of te kiezen
- toepassingen die gebruikers toestaan om optimizer-hints in te voeren of te kiezen tijdens runtime
- toepassingen die een database opvragen waar de gegevensdefinities van tabellen voortdurend veranderen
- toepassingen die een database opvragen waar vaak nieuwe tabellen worden aangemaakt
voor voorbeelden, zie “Querying Using Dynamic SQL: example”, en zie de query voorbeelden in “a dynamic SQL scenario using native Dynamic SQL”.,
Referentiebestandobjecten die niet bestaan bij de compilatie
veel typen toepassingen moeten interageren met gegevens die periodiek worden gegenereerd. U kent bijvoorbeeld de tabeldefinities tijdens het compileren, maar niet de namen van de tabellen.
dynamische SQL kan dit probleem oplossen, omdat het u laat wachten tot runtime om de tabelnamen op te geven. Bijvoorbeeld, in de sample data warehouse applicatie besproken in ” Wat is Dynamic SQL?”, nieuwe tabellen worden gegenereerd elk kwartaal, en deze tabellen hebben altijd dezelfde definitie., U kunt een gebruiker de naam van de tabel laten opgeven tijdens runtime met een dynamische SQL-query die vergelijkbaar is met de volgende:
dynamisch optimaliseren
u kunt dynamische SQL gebruiken om een SQL-statement te bouwen op een manier die de uitvoering optimaliseert door de hints dynamisch samen te voegen in een SQL-statement. Hiermee kunt u de hints wijzigen op basis van uw huidige database statistieken, zonder dat hercompilatie nodig is.,
bijvoorbeeld, de volgende procedure gebruikt een variabele genaamd a_hint
om gebruikers toe te staan een hint optie door te geven aan de SELECT
statement:
In dit voorbeeld kan de gebruiker een van de volgende waarden doorgeven voor a_hint
:
a_hint = '/*+ ALL_ROWS */'
a_hint = '/*+ FIRST_ROWS */'
a_hint = '/*+ CHOOSE */'
of een andere geldige hint optie.
zie ook:
Oracle9i Database Performance Guide and Reference voor meer informatie over het gebruik van hints.,
dynamische PL/SQL-blokken uitvoeren
u kunt de opdracht EXECUTE
IMMEDIATE
gebruiken om anonieme PL / SQL-blokken uit te voeren. U kunt Flexibiliteit toevoegen door de inhoud van het blok tijdens runtime te construeren.
bijvoorbeeld, stel dat y through throughou een toepassing wilt schrijven die een gebeurtenisnummer neemt en naar een handler voor de gebeurtenis stuurt. De naam van de handler is in de vorm EVENT_HANDLER_
event_num, waarbij event_num het nummer van de gebeurtenis is., Een aanpak is om de dispatcher te implementeren als een switch statement, waar de code behandelt elke gebeurtenis door het maken van een statische oproep aan de juiste handler. Deze code is niet erg uitbreidbaar omdat de dispatcher code moet worden bijgewerkt wanneer een handler voor een nieuwe gebeurtenis wordt toegevoegd.,
met behulp van native dynamic sql, kunt u een kleinere, meer flexibele gebeurtenis dispatcher schrijven, vergelijkbaar met de volgende:
dynamische bewerkingen uitvoeren met behulp van Invoker-rechten
met behulp van de invoker-rechten functie met dynamische SQL, kunt u toepassingen bouwen die dynamische SQL-statements uitgeven onder de privileges en het schema van de invoker. Deze twee functies, invoker-rechten en dynamic SQL, kunt u herbruikbare toepassing subcomponenten die kunnen werken op en toegang tot de gegevens en modules van de invoker te bouwen.,
zie ook:
PL / SQL gebruikershandleiding en referentie voor informatie over het gebruik van invokers-rechten en native dynamische SQL.,
een dynamisch SQL-Scenario met Native Dynamic SQL
dit scenario laat u zien hoe u de volgende bewerkingen met native dynamic sql kunt uitvoeren:
- DDL-en DML-bewerkingen uitvoeren
- enkele rij-en queries met meerdere rijen uitvoeren
de database in dit scenario is de personeelsdatabase van een bedrijf (genaamd hr
) met het volgende gegevensmodel:
een Mastertabel genaamd offices
bevat de lijst van alle bedrijfslocaties., De tabel offices
heeft de volgende definitie:
Column Name Null? Type LOCATION NOT_NULL VARCHAR2(200)
meerdere emp_
locatietabellen bevatten de werknemersinformatie, waarbij locatie de naam is van de plaats waar het kantoor zich bevindt. Een tabel met de naam emp_houston
bevat bijvoorbeeld informatie over werknemers voor het kantoor van het bedrijf in Houston, terwijl een tabel met de naam emp_boston
informatie over werknemers voor het kantoor van het bedrijf in Boston bevat.,
elke emp_
locatietabel heeft de volgende definitie:
de volgende secties beschrijven verschillende native dynamische SQL-bewerkingen die kunnen worden uitgevoerd op de gegevens in de hr
database.
Sample DML-bewerking met Native Dynamic SQL
de volgende native dynamic SQL-procedure geeft een verhoging aan alle werknemers met een bepaalde functie:
Sample DDL-bewerking met Native Dynamic SQL
de instructie EXECUTE IMMEDIATE
kan DDL-bewerkingen uitvoeren., De volgende procedure voegt bijvoorbeeld een kantoorlocatie toe:
de volgende procedure verwijdert een kantoorlocatie:
Sample Single-Row Query Using Native Dynamic SQL
het EXECUTE
IMMEDIATE
statement kan dynamische Single-row query ‘ s uitvoeren. U kunt bind-variabelen opgeven in deUSING
clausule en de resulterende rij ophalen in het doel dat is gespecificeerd in deINTO
clausule van het statement.,
de volgende functie haalt het aantal werknemers op een bepaalde locatie die een bepaalde taak uitvoeren:
Sample Multiple-Row Query met behulp van Native Dynamic SQL
De OPEN-FOR
, FETCH
, en CLOSE
statements kunnen dynamische query ‘ s met meerdere rijen uitvoeren., De volgende procedure toont bijvoorbeeld alle werknemers met een bepaalde taak op een bepaalde locatie:
kiezen tussen Native Dynamic SQL en het Dbms_sql-pakket
Oracle biedt twee methoden voor het gebruik van dynamische SQL binnen PL/SQL: native dynamic SQL en het DBMS_SQL
– pakket. Met Native dynamic sql kunt u dynamische SQL-statements rechtstreeks in PL/SQL-code plaatsen. Deze dynamische statements omvatten DML statements (inclusief queries), PL/SQL anonieme blokken, DDL statements, transaction control statements en Session control statements.,
To process most native dynamic SQL statements, you use the EXECUTE
IMMEDIATE
statement. To process a multi-row query (SELECT
statement), you use OPEN-FOR
, FETCH
, and CLOSE
statements.
Note:
To use native dynamic SQL, the COMPATIBLE
initialization parameter must be set to 8.1.0 or higher. See Oracle9i Database Migration for more information about the COMPATIBLE
parameter.,
hetDBMS_SQL
pakket is een PL/SQL-bibliotheek die een API biedt om SQL-statements dynamisch uit te voeren. HetDBMS_SQL
pakket heeft procedures om een cursor te openen, een cursor te ontleden, te leveren bindt, enzovoort. Programma ‘ s die het DBMS_SQL
pakket gebruiken, roepen dit pakket aan om dynamische SQL-bewerkingen uit te voeren.
de volgende paragrafen geven gedetailleerde informatie over de voordelen van beide methoden.,
zie ook:
The PL/SQL User ‘ s Guide and Reference for detailed information about using native dynamic SQL and the Oracle9i supplyed PL/SQL Packages and Types Reference for detailed information about using the DBMS_SQL
package. In de gebruikershandleiding en referentie van PL/SQL wordt native dynamic SQL simpelweg dynamische SQL genoemd.,
voordelen van Native Dynamic SQL
Native dynamic SQL biedt de volgende voordelen ten opzichte van het DBMS_SQL
pakket:
Native Dynamic SQL is eenvoudig te gebruiken
omdat native dynamic SQL is geïntegreerd met SQL, kunt u het gebruiken op dezelfde manier als u statische SQL gebruikt binnen PL / SQL-code. Native dynamische SQL-code is doorgaans compacter en leesbaar dan equivalente code die het DBMS_SQL
pakket gebruikt.,
met hetDBMS_SQL
pakket moet u veel procedures en functies in een strikte volgorde aanroepen, waardoor zelfs eenvoudige operaties veel code vereisen. U kunt deze complexiteit voorkomen door in plaats daarvan native dynamic sql te gebruiken.
tabel 8-1 illustreert het verschil in de hoeveelheid code die nodig is om dezelfde bewerking uit te voeren met behulp van het DBMS_SQL
pakket en native dynamic SQL.,
tabel 8-1 Code vergelijking van Dbms_sql pakket en Native dynamische SQL
Native dynamische SQL is sneller dan Dbms_sql
Native dynamische SQL in PL/SQL presteert vergelijkbaar met de prestaties van statische SQL, omdat de PL / SQL interpreter heeft ingebouwde ondersteuning voor het. Programma ’s die native dynamic SQL gebruiken zijn veel sneller dan Programma’ s die het DBMS_SQL
pakket gebruiken. Typisch, native dynamische SQL statements presteren 1,5 tot 3 keer beter dan equivalent DBMS_SQL
aanroepen. (Uw prestatiewinst kan variëren afhankelijk van uw toepassing.,)
Native dynamic SQL bundelt de stappen voor het voorbereiden, binden en uitvoeren van statements in één enkele bewerking, waardoor het kopiëren van gegevens en de aanroep overhead van de procedure worden geminimaliseerd en de prestaties worden verbeterd.
het DBMS_SQL
pakket is gebaseerd op een procedurele API en maakt gebruik van high procedure call en data copy overhead. Elke keer dat u een variabele bindt, kopieert hetDBMS_SQL
pakket de PL/SQL bind variabele in zijn ruimte voor gebruik tijdens het uitvoeren., Elke keer dat u een fetch uitvoert, worden de gegevens gekopieerd naar de ruimte die wordt beheerd door het DBMS_SQL
pakket en vervolgens worden de opgehaalde gegevens één kolom per keer gekopieerd naar de juiste PL/SQL variabelen, wat resulteert in aanzienlijke overhead.
Prestatietip: Bind-variabelen
bij gebruik van native dynamic sql of het DBMS_SQL
pakket, kunt u de prestaties verbeteren door bind-variabelen te gebruiken, omdat bind-variabelen Oracle toestaan om een enkele cursor te delen voor meerdere SQL-statements.,
bijvoorbeeld, de volgende standaard dynamische SQL-code gebruikt bind-variabelen niet:
voor elke afzonderlijke my_deptno
variabele wordt een nieuwe cursor aangemaakt, waardoor resource contention en slechte prestaties worden veroorzaakt. Bind my_deptno
als bind-variabele:
Hier wordt dezelfde cursor hergebruikt voor verschillende waarden van de bind my_deptno
, wat de prestaties en schaalbaarheid verbetert.,
Native Dynamic SQL ondersteunt door de gebruiker gedefinieerde typen
Native dynamic SQL ondersteunt alle typen die door statische SQL in PL/SQL worden ondersteund, inclusief door de gebruiker gedefinieerde typen zoals door de gebruiker gedefinieerde objecten, collecties enREFs
. Het pakket DBMS_SQL
ondersteunt deze door de gebruiker gedefinieerde types niet.
hetDBMS_SQL
pakket biedt beperkte ondersteuning voor arrays. Zie de door Oracle9i geleverde PL/SQL-pakketten en-Types referentie voor informatie.,
Native dynamische SQL ondersteunt het ophalen in Records
Native dynamische SQL en statische SQL ondersteunen beide het ophalen in records, maar het DBMS_SQL
pakket niet. Met native dynamic SQL kunnen de rijen die voortvloeien uit een query direct worden opgehaald in PL/SQL-records.,
in het volgende voorbeeld worden de rijen van een query opgehaald in de emp_rec
record:
voordelen van het Dbms_sql-pakket
het DBMS_SQL
biedt de volgende voordelen ten opzichte van native dynamische SQL:
DBMS_SQL wordt ondersteund in Client-Side programma ‘ s
het DBMS_SQL
pakket wordt ondersteund in programma ‘ s aan de clientzijde, maar native Dynamic sql niet., Elke aanroep naar hetDBMS_SQL
pakket van het client-side programma vertaalt zich naar een PL/SQL remote procedure call (RPC); deze aanroep vindt plaats wanneer u een variabele moet binden, een variabele moet definiëren of een statement moet uitvoeren.
DBMS_SQL ondersteunt DESCRIBE
deDESCRIBE_COLUMNS
procedure in hetDBMS_SQL
pakket kan worden gebruikt om de kolommen te beschrijven voor een cursor geopend en ontleed doorDBMS_SQL
. Deze functie is vergelijkbaar met het DESCRIBE
commando in SQL*Plus., Native dynamische SQL heeft geenDESCRIBE
faciliteit.
DBMS_SQL Ondersteunt meerdere rij-Updates en verwijdert met een terugkerende Clausule
het DBMS_SQL
pakket ondersteunt statements met een RETURNING
clausule die meerdere rijen bijwerken of verwijderen. Native dynamic SQL ondersteunt alleen eenRETURNING
clausule als een enkele rij wordt geretourneerd.,
See Also:
“Performing DML with RETURNING Clause Using Dynamic SQL: Example” for examples of DBMS_SQL
package code and native dynamic SQL code that uses a RETURNING
clause.
DBMS_SQL Supports SQL Statements Larger than 32KB
The DBMS_SQL
package supports SQL statements larger than 32KB; native dynamic SQL does not.
DBMS_SQL Lets You Reuse SQL Statements
The PARSE
procedure in the DBMS_SQL
package parses a SQL statement once., Na de eerste parsing kunt u het statement meerdere keren gebruiken met verschillende sets bind-argumenten.
Native dynamic SQL bereidt elke keer dat het statement wordt gebruikt een SQL-statement voor, wat meestal gepaard gaat met parsing, optimalisatie en het genereren van plannen. Hoewel de extra prepare-operaties een kleine prestatiefout veroorzaken, wordt de vertraging meestal gecompenseerd door de prestatievoordelen van native dynamic SQL.,
voorbeelden van Dbms_sql pakketcode en Native dynamische SQL-Code
de volgende voorbeelden illustreren de verschillen in de code die nodig is om bewerkingen met de DBMS_SQL
pakket en native dynamische SQL te voltooien. In het bijzonder worden de volgende soorten voorbeelden gepresenteerd:
- een query
- een DML-operatie
- een DML-retouroperatie
in het algemeen is de native dynamic SQL-code leesbaarder en compacter, wat de productiviteit van ontwikkelaars kan verbeteren.,
het Opvragen van het Gebruik van Dynamische SQL: Voorbeeld
in Het volgende voorbeeld bevat een dynamische query statement met één binden variabele (:jobname
) en twee kolommen selecteren (ename
en sal
):
stmt_str := 'SELECT ename, sal FROM emp WHERE job = :jobname';
in Dit voorbeeld query ‘ s voor werknemers met de functieomschrijving SALESMAN
in de job
kolom van de emp
tabel. Tabel 8-2 toont voorbeeldcode die deze query uitvoert met behulp van hetDBMS_SQL
pakket en native dynamic SQL.,
Table 8-2 Querying Using the Dbms_sql Package and Native Dynamic SQL
uitvoeren van DML met behulp van dynamische SQL: voorbeeld
het volgende voorbeeld bevat een dynamisch INSERT
statement voor een tabel met drie kolommen:
stmt_str := 'INSERT INTO dept_new VALUES (:deptno, :dname, :loc)';
dit voorbeeld voegt een nieuwe rij in waarvoor de kolom waarden zijn in de PL/SQL variabelen deptnumber
, deptname
, en location
. Tabel 8-3 toont de voorbeeldcode die deze DML operatie uitvoert met behulp van hetDBMS_SQL
pakket en native dynamic SQL.,
Tabel 8-3 DML Bediening met Behulp van de DBMS_SQL Pakket en eigen Dynamische SQL
het Uitvoeren van DML met het TERUGSTUREN van het Component met Behulp van Dynamische SQL: Voorbeeld
in Het volgende voorbeeld wordt een dynamische UPDATE
statement voor een update van de locatie van een afdeling, dan geeft de naam van de afdeling:
stmt_str := 'UPDATE dept_new SET loc = :newloc WHERE deptno = :deptno RETURNING dname INTO :dname';
Tabel 8-4 voorbeeld van code die volbrengt deze bewerking met zowel de DBMS_SQL
pakket en eigen dynamische SQL.,
tabel 8-4 DML retournering met behulp van het Dbms_sql-pakket en Native Dynamic SQL
met behulp van dynamische SQL in andere talen dan PL/SQL
hoewel dit hoofdstuk PL/SQL-ondersteuning voor dynamische SQL bespreekt, kunt u dynamische SQL vanuit andere talen aanroepen:
- Als u C/c++ gebruikt, kunt u dynamische SQL aanroepen met de Oracle Call Interface (OCI), of u kunt de Pro*C/C++ PRECOMPILER gebruiken om dynamische SQL-extensies aan uw C-code toe te voegen.
- als u COBOL gebruikt, kunt u de pro*COBOL precompiler gebruiken om dynamische SQL extensies aan uw COBOL code toe te voegen.,
- Als u Java gebruikt, kunt u toepassingen ontwikkelen die dynamische SQL met JDBC gebruiken.
Als u een toepassing hebt die OCI, Pro*C/C++ of Pro*COBOL gebruikt om dynamische SQL uit te voeren, moet u overwegen om over te schakelen naar native dynamische SQL binnen PL/SQL opgeslagen procedures en functies. De netwerk round-trips die nodig zijn om dynamische SQL-bewerkingen uit te voeren vanuit client-side applicaties kunnen de prestaties schaden. Opgeslagen procedures kunnen zich op de server bevinden, waardoor de netwerkoverhead wordt geëlimineerd., U kunt de PL/SQL opgeslagen procedures en opgeslagen functies bellen vanuit de OCI, Pro*C/C++, of Pro*COBOL applicatie.,br>Zie Ook:
Voor informatie over het aanroepen van opgeslagen procedures van Oracle worden opgeslagen en functies van de verschillende talen refereer je naar:
- Oracle Call Interface Programmer ’s Guide
- Pro*C/C++ Precompiler Programmer’ s Guide
- Pro*COBOL Precompiler Programmer ’s Guide
- Oracle9i Stored Procedures Developer’ s Guide
het Gebruik van PL/SQL Records in SQL INSERT en UPDATE-Instructies
Hoewel u kunt opsommen elk veld van een PL/SQL-record bij het plaatsen of bijwerken van de rijen in een tabel, de resulterende code is niet bijzonder leesbaar of te onderhouden., In plaats daarvan kun je PL/SQL records direct gebruiken in deze statements. De meest handige techniek is om de record te declareren met behulp van een % ROWTYPE attribuut, zodat het precies dezelfde velden heeft als de SQL tabel.
hoewel deze techniek helpt om PL/SQL variabelen en types nauwer te integreren met SQL DML statements, kunt u PL/SQL records niet gebruiken als bind variabelen in dynamische SQL statements.
Geef een reactie