J'ai une question concernant l'endroit où les variables de liaison peuvent être utilisées dans une instruction SQL dynamique en PL/SQL.
Par exemple, je sais que cela est valide:
CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2)
RETURN NUMBER
IS
v_query_str VARCHAR2(1000);
v_num_of_employees NUMBER;
BEGIN
v_query_str := 'SELECT COUNT(*) FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job';
EXECUTE IMMEDIATE v_query_str
INTO v_num_of_employees
USING p_job;
RETURN v_num_of_employees;
END;
/
Je me demandais si vous pouviez utiliser une variable de liaison dans une instruction select comme celle-ci
CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2)
RETURN NUMBER
IS
v_query_str VARCHAR2(1000);
v_num_of_employees NUMBER;
BEGIN
v_query_str := 'SELECT COUNT(*) INTO :into_bind FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job';
EXECUTE IMMEDIATE v_query_str
USING out v_num_of_employees, p_job;
RETURN v_num_of_employees;
END;
/
Remarque J'ai utilisé une instruction SELECT INTO comme chaîne dyamic et une variable de liaison dans la clause INTO.
Je suis actuellement en voyage et je n'aurai pas accès à mon ordinateur à la maison pendant quelques jours, mais cela me harcèle depuis un moment. J'ai essayé de lire la référence PL/SQL mais ils n'ont pas d'exemple de sélection comme celle-ci.
Merci
Non, vous ne pouvez pas utiliser les variables de liaison de cette façon. Dans votre deuxième exemple, :into_bind
dans v_query_str
est simplement un espace réservé pour la valeur de la variable v_num_of_employees
. Votre déclaration select se transformera en quelque chose comme:
SELECT COUNT(*) INTO FROM emp_...
parce que la valeur de v_num_of_employees
est null
à EXECUTE IMMEDIATE
.
Votre premier exemple présente la manière correcte de lier la valeur de retour à une variable.
Modifier
L’affiche originale a modifié le deuxième bloc de code auquel je me réfère dans ma réponse en utilisant le paramètre OUT
en mode v_num_of_employees
au lieu du mode par défaut IN
. Cette modification rend les deux exemples fonctionnellement équivalents.
À mon avis, un bloc PL/SQL dynamique est quelque peu obscur. Bien que très flexible, il est également difficile à régler, difficile à déboguer et à comprendre ce qui se passe ... Mon vote va vers votre première option,
EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;
Les deux utilisent des variables de liaison, mais d’abord, pour moi, est plus redéfinissable et ajustable que l’option @jonearles.
Placez l'instruction select dans un bloc PL/SQL dynamique.
CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2)
RETURN NUMBER
IS
v_query_str VARCHAR2(1000);
v_num_of_employees NUMBER;
BEGIN
v_query_str := 'begin SELECT COUNT(*) INTO :into_bind FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job; end;';
EXECUTE IMMEDIATE v_query_str
USING out v_num_of_employees, p_job;
RETURN v_num_of_employees;
END;
/
La variable de liaison peut être utilisée dans une requête SQL Oracle avec la clause "in".
Fonctionne en 10g; Je ne sais pas pour les autres versions.
La variable de liaison est varchar jusqu'à 4000 caractères.
Exemple: Variable de liaison contenant une liste de valeurs séparées par des virgules, par ex.
: bindvar = 1,2,3,4,5
select * from mytable
where myfield in
(
SELECT regexp_substr(:bindvar,'[^,]+', 1, level) items
FROM dual
CONNECT BY regexp_substr(:bindvar, '[^,]+', 1, level) is not null
);
(Même information que j'ai posté ici: Comment spécifiez-vous la clause IN dans une requête dynamique utilisant une variable? )