Rotorsaken
I Oracle har du tre typer av SQL-satser (och dessutom finns det PL/SQL-block):
- Uttalanden i Data Definiton Language (DDL). Dessa uttalanden ändrar strukturen i databasen. De börjar vanligtvis med verben "ALTER" eller "CREATE"
- Uttalanden i Data Modification Language (DML). Där satser modifierar innehållet inuti tabeller och lämnar strukturen för varje tabell oförändrad. Dessa påståenden börjar vanligtvis med "INSERT", "MERGE" eller "DELETE".
- Uttalanden på vad jag kallar "frågespråk" (det verkar inte finnas något kanoniskt namn för dessa). Dessa uttalanden börjar med verbet "SELECT".
Bindningsvariabler i Oracle är endast tillåtna på vissa speciella platser i DML och frågesatser. Du försöker använda bindningsvariabler på platser där de inte är tillåtna. Därav felet.
Lösning
Bygg ditt uttalande utan bindningsvariabler. Bygg hela frågesträngen istället med strängsammansättning.
Om du vill rensa indata innan du sammanfogar strängen, använd paketet DBMS_ASSERT.
Bakgrund
Bindningsvariabler kan endast användas när Oracle kan bygga en frågeplan utan att känna till variabelns värde. För DDL-satser finns det ingen frågeplan. Därför är bindningsvariabler inte tillåtna.
I DML och frågesatser är bindningsvariabler endast tillåtna när de används i en tupel (avseende den underliggande mängdteorin), dvs när värdet kommer att jämföras med värdet i en tabell eller när värdet kommer att infogas i en tabell . De får inte ändra strukturen för genomförandeplanen (t.ex. att ändra måltabellen eller att ändra antalet jämförelser).