update query immediate example ejemplos ejemplo dinamica consulta sql oracle plsql oracle11g execute-immediate

immediate - oracle pl sql execute dynamic query



Usar variables de vinculación con la cláusula dinámica SELECT INTO en PL/SQL (5)

Tengo una pregunta sobre dónde se pueden usar las variables de vinculación en una declaración SQL dinámica en PL / SQL.

Por ejemplo, sé que esto es válido:

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; /

Me preguntaba si podría usar una variable de vinculación en una declaración de selección como esta

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; /

Nota: utilicé una instrucción SELECT INTO como mi cadena dyamic y usé una variable bind en la cláusula INTO.

Actualmente estoy de viaje y no tendré acceso a mi computadora en mi casa por unos días, pero esto me ha estado molestando un poco. Intenté leer la referencia PL / SQL, pero no tienen un ejemplo de una selección como esta.

Gracias


Coloque la instrucción de selección en un bloque dinámico PL / SQL.

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; /


En mi opinión, un bloque dinámico PL / SQL es algo oscuro. Si bien es muy flexible, también es difícil de sintonizar, difícil de depurar y difícil de descifrar qué ocurre. Mi voto va a su primera opción,

EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;

Ambos usos vinculan variables, pero primero, para mí, es más modificable y ajustable que la opción @jonearles.


La variable de vinculación se puede utilizar en la consulta SQL de Oracle con la cláusula "in".

Funciona en 10g; No sé sobre otras versiones.

La variable de enlace es varchar hasta 4000 caracteres.

Ejemplo: variable de vinculación que contiene una lista de valores separados por comas, por ejemplo

: 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 );

(La misma información que publiqué aquí: ¿cómo se especifica cláusula IN en una consulta dinámica usando una variable? )


No, no puedes usar las variables de vinculación de esa manera. En su segundo ejemplo :into_bind en v_query_str es solo un marcador de posición para el valor de la variable v_num_of_employees . Su declaración select into se convertirá en algo así como:

SELECT COUNT(*) INTO FROM emp_...

porque el valor de v_num_of_employees es null en EXECUTE IMMEDIATE .

Su primer ejemplo presenta la forma correcta de enlazar el valor de retorno a una variable.

Editar

El póster original ha editado el segundo bloque de código al que me refiero en mi respuesta para usar el modo de parámetro OUT para v_num_of_employees lugar del modo IN predeterminado. Esta modificación hace que los dos ejemplos sean funcionalmente equivalentes.


Seleccionar en funcionalidad solo funciona para PL / SQL Block, cuando utiliza Execute immediate, oracle interpreta v_query_str como una cadena de consulta SQL para que no pueda usar .will get keyword missing Exception. en el ejemplo 2, estamos utilizando begin end; por lo que se convirtió en bloque pl / sql y es legal.