Использование переменных привязки с динамическим предложением SELECT INTO в PL / SQL
у меня есть вопрос о том, где переменные Привязки могут использоваться в динамической инструкции SQL в 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 := '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;
/
мне было интересно, можете ли вы использовать переменные привязки в операторе select, как это
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;
/
Примечание. я использовал оператор SELECT INTO в качестве моей строки dyamic и использовал переменную bind в предложении INTO.
в настоящее время я путешествую прямо сейчас и не буду иметь доступа к моему компьютеру вернулся домой на несколько дней, но это меня немного беспокоит. Пробовал читать ссылку PL/SQL, но у них нет примера такого выбора.
спасибо
5 ответов
нет, вы не можете использовать переменные связывания, таким образом. Во втором примере :into_bind
на v_query_str
это просто местозаполнитель значение переменной v_num_of_employees
. Ваше заявление select into превратится во что-то вроде:
SELECT COUNT(*) INTO FROM emp_...
потому что значение v_num_of_employees
is null
at EXECUTE IMMEDIATE
.
в первом примере представлен правильный способ привязки возвращаемого значения к переменной.
редактировать
оригинальный плакат отредактировал второй блок кода, на который я ссылаюсь в своем ответе, чтобы использовать OUT
режим параметр для v_num_of_employees
вместо IN
режим. Эта модификация делает оба примера функционально эквивалентны.
на мой взгляд, динамический блок PL/SQL несколько неясен. В то время как очень гибкий, также трудно настроить, трудно отлаживать и трудно понять, что происходит. Мой голос идет к вашему первому варианту,
EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;
как использование переменных связывания, но во-первых, для меня redeable и особенности чем вариант @jonearles.
поместите инструкцию select в динамический блок 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;
/
переменная Bind может использоваться в запросе Oracle SQL с предложением "in".
работает в 10g; я не знаю о других версиях.
переменная Bind-это varchar до 4000 символов.
пример: привязка переменной, содержащей список значений, разделенных запятыми, например
: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
);
(та же информация, что и здесь:Как указать предложение IN в динамическом запросе с помощью переменной? )
Select Into functionality работает только для блока PL/SQL, когда вы используете Execute immediate , oracle интерпретирует v_query_str как строку SQL-запроса, поэтому вы не можете использовать into .получит ключевое слово missing Exception. в Примере 2 мы используем begin end; поэтому он стал блоком pl/sql и его законным.