Quand j'ai une instruction sql comme select * from table1
, ça marche très bien, mais dès que je le mets dans une fonction, j'obtiens:
ORA-00942: table or view does not exist
Comment résoudre ça?
Il y a deux ou trois choses que vous pourriez examiner. Selon votre question, il semble que le propriétaire de la fonction soit différent du propriétaire de la table.
1) Subventions via un rôle: pour créer des procédures et des fonctions stockées sur les objets d'un autre utilisateur, vous avez besoin d'un accès direct aux objets (au lieu d'un accès via un rôle).
2)
Par défaut, les procédures stockées et les méthodes SQL s'exécutent avec les privilèges de leur propriétaire et non de leur utilisateur actuel.
Si vous avez créé une table dans le schéma A et la fonction dans le schéma B, vous devez consulter les concepts d'Oracle Invoker/Definer Rights pour comprendre ce qui pourrait être à l'origine du problème.
http://download.Oracle.com/docs/cd/B19306_01/appdev.102/b14261/subprograms.htm#LNPLS00809
Il y a de fortes chances que les privilèges de sélection dans le tableau 1 aient été accordés à un rôle, et le rôle vous a été accordé. Les privilèges accordés à un rôle ne sont pas disponibles pour PL/SQL écrits par un utilisateur, même si l'utilisateur a reçu le rôle.
Vous voyez cela beaucoup pour les utilisateurs qui ont reçu le rôle dba sur les objets appartenant à sys. Un utilisateur avec un rôle dba pourra, par exemple, SELECT * from V$SESSION
, mais ne pourra pas écrire une fonction incluant SELECT * FROM V$SESSION
.
Le correctif consiste à accorder directement à l'utilisateur des autorisations explicites sur l'objet en question, par exemple, dans le cas ci-dessus, l'utilisateur SYS doit GRANT SELECT ON V_$SESSION TO MyUser;
Assurez-vous que la fonction se trouve dans le même schéma de base de données que la table.
Soit vous n'avez pas l'autorisation pour ce schéma/table OR la table existe. La plupart du temps, ce problème s'est produit si vous utilisez d'autres tables de schéma dans vos procédures stockées. Par exemple. Si vous exécutez la procédure stockée à partir de l'utilisateur/schéma ABC et dans le même PL/SQL il y a des tables qui proviennent de l'utilisateur/schéma XYZ. Dans ce cas, ABC devrait avoir GRANT c'est-à-dire les privilèges des tables XYZ
Accordez tout sur ABC;
Select * From Dba_Tab_Privs Where Owner = 'XYZ'and Table_Name = <Table_Name>;
Une solution très simple consiste à ajouter le nom de la base de données avec le nom de votre table comme si votre nom de base de données est DBMS
et la table est info
alors ce sera DBMS.info
pour toute requête.
Si votre requête est
select * from STUDENTREC where ROLL_NO=1;
cela pourrait montrer une erreur mais
select * from DBMS.STUDENTREC where ROLL_NO=1;
ce n'est pas le cas parce que maintenant votre table est trouvée.