J'ai un script pl\sql où je veux définir le nom de table utilisé dans le script sur une variable. Donc, à partir de quelques exemples que j'ai trouvés sur le Web, j'ai écrit le code ci-dessous. La première section fonctionne, donc je pense que ma syntaxe générale est correcte, mais la deuxième section, où j'essaie d'utiliser une variable pour un nom de table, il erreurs ("Erreur SQL: ORA-00903: nom de table invalide = ").
Tout le monde sait ce que je fais mal ... Je ne fais pas beaucoup de PL\SQL alors peut-être que je manque juste quelque chose d'évident.
--works
variable numOfrecords number;
exec :numOfrecords := 10;
select * from customers2008 where rownum < :numOfrecords;
--does not work
variable tableNm CHAR;
exec :tableNm := 'customers2008';
print tableNm;
select * from :tableNm;
Si vous exécutez ce script à partir de sqlplus (ce qui semble être le cas), vous souhaitez utiliser la commande DEFINE, qui vous permet de créer des variables de substitution sqlplus qui ne sont qu'une substitution de chaîne directe, par exemple:
define tableNm = 'customers2008'
select * from &tableNm;
Voir tilisation de Sql * Plus pour plus d'informations sur leur utilisation. Vous pouvez transmettre des valeurs dans votre script à partir de la ligne de commande en utilisant les variables de poste de position prédéfinies, comme ceci:
define tableNm = &1
select * from &tableNm;
... puis invoquez sqlplus comme ceci:
sqlplus user/pwd@server @myscript.sql customers2008
Si vous ne transmettez pas de valeur sur la ligne de commande, l'invocateur de script sera invité à entrer la valeur.
Voir la réponse de Dave Costa ci-dessous pour les différences entre les variables de liaison et de substitution.
Pour essayer d'ajouter quelques explications:
La méthode que vous essayez d'utiliser s'appelle variable de liaison. Une variable de liaison est identifiée dans Oracle SQL par un signe deux-points suivi d'un identificateur. Le but d'une variable de liaison est que sa valeur n'a pas besoin d'être connue lors de l'analyse de l'instruction SQL; l'instruction peut être analysée une fois, puis exécutée plusieurs fois avec différentes valeurs liées à la variable.
Pour qu'une instruction SQL soit analysée, les noms de table et de colonne impliqués doivent être connus. Le nom de la table ne peut donc pas être représenté par une variable de liaison, car la valeur ne serait pas connue au moment de l'analyse.
Si vous exécutez simplement SQL et PL/SQl en ligne via SQLPlus, les variables de substitution sont un moyen facile de résoudre ce problème, comme Steve l'a expliqué. Une variable de substitution est remplacée par sa valeur lorsque le client SQLPlus lit la commande, avant même de l'envoyer à Oracle pour analyse.
Vous devez faire quelque chose comme ceci:
EXECUTE IMMEDIATE 'select * from' || tableNm;
En effet, Oracle n'autorise pas la liaison de variables pour la table (ou tout autre nom d'objet).
L'approche EXECUTE IMMEDIATE a des implications de sécurité importantes: lorsque la valeur tableNm est fournie par l'utilisateur, vous êtes largement ouvert aux attaques injection SQL .
Variables de substitution travail:
SQL> select * from &table_name;
Enter value for table_name: dual
old 1: select * from &table_name
new 1: select * from dual
D
-
X