À l'aide de Pragma dans le Corps de Package Oracle
J'aimerais créer un Package Oracle et deux fonctions: Une fonction publique ( function_public
) et un privé ( function_private
). La fonction publique utilise le secteur privé dans une instruction sql.
Sans pragma le code ne compile pas (PLS-00231: function 'FUNCTION_PRIVATE' may not be used in SQL
)
CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
END PRAGMA_TEST;
CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
return 'z';
END;
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
ret VARCHAR2(100);
BEGIN
SELECT 'x' || function_private(x) INTO ret FROM dual;
return ret;
END;
END PRAGMA_TEST;
Le code se compile si j'ajoute WNDS, WNPS
pragma pour function_private
. Il me semble pragma peut être utilisée que dans la déclaration du package, et pas dans le corps de package, donc je dois déclarer function_private
dans le paquetage:
CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES( function_private, WNDS, WNPS);
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
END PRAGMA_TEST;
CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
return 'z';
END;
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
ret VARCHAR2(100);
BEGIN
SELECT 'x' || function_private(x) INTO ret FROM dual;
return ret;
END;
END PRAGMA_TEST;
Cette solution rend mon function_private
public. Est-il une solution pour ajouter pragma d'une fonction qui peut être trouvée que dans le corps de package?
Mise à JOUR: Remplacé le pseudo-code d'un exemple (simplifié).
UPDATE2: Corrections de bugs dans le code, tel que suggéré par Rob van Wijk.
OriginalL'auteur asalamon74 | 2010-05-10
Vous devez vous connecter pour publier un commentaire.
Votre problème n'a rien à voir avec les PRAGMAs. Rob dit, moderne versions d'Oracle répondre à la plupart de ce automatiquement.
Le problème est que vous ne pouvez pas appeler les fonctions privées à partir d'une instruction SQL, même ceux incorporé dans un autre sous-programme dans le même package. Lorsque PL/SQL exécute SQL, il est transféré au moteur SQL pour l'exécution, et qui tient essentiellement à l'extérieur du champ d'application de l'emballage, de sorte qu'il n'a pas accès aux membres privés.
Cette compile sans problème, pas de pragmas, mais en faisant le "privé" de la fonction publique:
Si vous voulez garder la fonction privée, vous devez voir si vous pouvez réécrire la fonction publique, de telle manière que l'appel à la fonction privée se fait à l'extérieur de l'instruction SQL:
OriginalL'auteur Dave Costa
Votre
function_private
est déclaré seulement dans le corps de package, de sorte que son champ d'application est limité uniquement à d'autres procédures dans votre forfait. Par conséquent, il devra se conformer à la pureté niveau de ceux de l'appel de procédures ou d'autre, le compilateur va lancer une exception.Comparer ce coffre déclaration (remarque, j'ai étendu la pureté de la
function_public
) ...... avec ce dangereux ...
Le point de la RESTRICTS_REFERENCES pragma est que les procédures déclarées dans le package de spécification peut être utilisé par d'autres paquets, même les instructions SQL, appartenant ou exécutés par d'autres utilisateurs (schémas), qui pourraient ne pas avoir accès à notre corps de package source. Le pragma est une méthode par laquelle nous vous proposons des assurances au sujet de l'impact de l'intégration de notre code dans le leur. C'est pourquoi le pragma doit être déclarée dans la spec, parce que c'est la seule partie du code exposés lorsque nous accorder EXÉCUTER sur le paquet à un autre utilisateur.
modifier
Ah, après avoir vu votre code révisé exemple, je comprends ce que vous essayez de faire. Ce n'est pas, ne sera pas, ne peut pas fonctionner. Nous sommes seulement autorisés à utiliser emballés fonctions qui ont été déclarées dans la spec = fonctions publiques - en SQL. Il n'a pas d'importance si le SQL est écrit dans SQL*Plus ou codées dans un autre emballés procédure. La raison en est tout à fait clair dans la pile d'erreur:
Le compilateur lance
ORA-00904: invalid identifier
parce que la fonction n'est pas déclaré dans la spec; il n'a rien à voir avec les niveaux de pureté,une remarque au sujet de la portée
PL/SQL n'est pas entièrement composé en ce qui concerne ses règles de portée: nous pouvons utiliser les variables dans notre emballés instruction SQL:
C'est que des fonctions et des types de wm doit déclarer, dans le spec si nous voulons les utiliser dans les instructions SQL.
OriginalL'auteur APC
Vous écrivez "je voudrais ajouter WNDS, WNPS pragma ...". Pourquoi aimez-vous? Depuis la version 9 (je crois), Oracle n'cette case pour vous. La seule raison pour laquelle vous voudrez peut-être ajouter la pragma-vous, c'est quand:
vous savez où dans une instruction SQL que vous voulez utiliser la fonction ET
vous connaissez des niveaux de pureté sont nécessaires pour cette utilisation ET
vous souhaitez trouver des violations au moment de la compilation au lieu de courir de temps
L'option la plus facile est de sauter tous les pragma déclarations tout à fait.
Avoir dit que, vous pouvez omettre le restrict_references pragma pour function_private si vous ajoutez le mot-clé de la CONFIANCE à l'restrict_references pragma de function_public.
http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96590/adg10pck.htm#21958
Ce qui concerne,
Rob.
La FIDUCIE mot-clé résolu un de mes problèmes, merci.
OriginalL'auteur Rob van Wijk
Oracle n'cette case.
Le code suivant ne compile pas, depuis
function_public
a la pragmaRNDS
, et il appellefunction_private
qui lit une table.Supprimer la
SELECT
defunction_private
et il fonctionne.OriginalL'auteur Peter Lang