Oracle
 sql >> Database >  >> RDS >> Oracle

come passare la variabile dallo script della shell a sqlplus

Sembra che tu abbia un heredoc contenente un singolo comando SQL*Plus, anche se non sembra corretto come indicato nei commenti. Puoi passare un valore in heredoc :

sqlplus -S user/[email protected] << EOF
@/opt/D2RQ/file.sql BUILDING
exit;
EOF

o se BUILDING è $2 nel tuo script:

sqlplus -S user/[email protected] << EOF
@/opt/D2RQ/file.sql $2
exit;
EOF

Se il tuo file.sql aveva un exit alla fine sarebbe ancora più semplice in quanto non avresti bisogno del heredoc :

sqlplus -S user/[email protected] @/opt/D2RQ/file.sql $2

Nel tuo SQL puoi quindi fare riferimento ai parametri di posizione usando le variabili di sostituzione:

...
}',SEM_Models('&1'),NULL,
...

Il &1 verrà sostituito con il primo valore passato allo script SQL, BUILDING; poiché si tratta di una stringa, deve ancora essere racchiusa tra virgolette. Potresti voler set verify off per interrompere se ti vengono mostrate le sostituzioni nell'output.

Puoi passare più valori e farvi riferimento in sequenza proprio come faresti con i parametri posizionali in uno script di shell:il primo parametro passato è &1 , il secondo è &2 , ecc. Puoi usare variabili di sostituzione ovunque nello script SQL, quindi possono essere usate come alias di colonna senza problemi:devi solo stare attento ad aggiungere un parametro extra che lo aggiungi alla fine dell'elenco (il che rende la numerazione fuori ordine nello script, potenzialmente) o regola tutto in modo che corrisponda:

sqlplus -S user/[email protected] << EOF
@/opt/D2RQ/file.sql total_count BUILDING
exit;
EOF

oppure:

sqlplus -S user/[email protected] << EOF
@/opt/D2RQ/file.sql total_count $2
exit;
EOF

Se total_count viene passato allo script della shell, quindi usa semplicemente il suo parametro posizionale, $4 o altro. E il tuo SQL sarebbe quindi:

SELECT COUNT(*) as &1
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&2'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

Se si passano molti valori, potrebbe risultare più chiaro utilizzare i parametri posizionali per definire parametri denominati, quindi eventuali problemi di ordinamento vengono tutti risolti all'inizio dello script, dove sono più facili da gestire:

define MY_ALIAS = &1
define MY_MODEL = &2

SELECT COUNT(*) as &MY_ALIAS
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&MY_MODEL'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

Dalla tua domanda separata, forse volevi solo:

SELECT COUNT(*) as &1
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&1'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

... quindi l'alias sarà lo stesso valore su cui stai interrogando (il valore in $2 o BUILDING nella parte originale della risposta). Puoi fare riferimento a una variabile di sostituzione tutte le volte che vuoi.

Potrebbe non essere facile da usare se lo esegui più volte, poiché apparirà come un'intestazione sopra il valore di conteggio in ogni bit di output. Forse questo sarebbe più analizzabile in seguito:

select '&1' as QUERIED_VALUE, COUNT(*) as TOTAL_COUNT

Se set pages 0 e set heading off , le tue chiamate ripetute potrebbero apparire in un elenco ordinato. Potrebbe anche essere necessario set tab off ed eventualmente utilizzare rpad('&1', 20) o simili per rendere quella colonna sempre della stessa larghezza. Oppure ottieni i risultati come CSV con:

select '&1' ||','|| COUNT(*)

Dipende per cosa stai usando i risultati...