45

我有一个关于绑定变量可以在 PL/SQL 中的动态 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;
/

我想知道您是否可以在这样的选择语句中使用绑定变量

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 语句作为我的动态字符串,并在 INTO 子句中使用了一个绑定变量。

我现在正在旅行,几天内将无法在家中使用我的电脑,但这一直困扰着我。尝试阅读 PL/SQL 参考,但他们没有这样的选择示例。

谢谢

4

5 回答 5

30

在我看来,动态 PL/SQL 块有点晦涩难懂。虽然非常灵活,但也很难调整、难以调试并且很难弄清楚发生了什么。我的票投给你的第一个选项,

EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;

两者都使用绑定变量,但首先,对我来说,它比@jonearles 选项更可重做和可调整。

于 2011-10-19T07:27:01.677 回答
28

不,您不能那样使用绑定变量。在您的第二个示例:into_bind中, inv_query_str只是变量值的占位符v_num_of_employees。您的 select into 语句将变成如下内容:

SELECT COUNT(*) INTO  FROM emp_...

因为v_num_of_employees的值为nullEXECUTE IMMEDIATE

您的第一个示例展示了将返回值绑定到变量的正确方法。

编辑

原始海报编辑了我在回答中提到的第二个代码块,以使用OUT参数模式v_num_of_employees而不是默认IN模式。此修改使两个示例在功能上等效。

于 2011-10-19T04:35:48.970 回答
19

将 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;
/
于 2011-10-19T04:49:44.970 回答
0

绑定变量可以在带有“in”子句的 Oracle SQL 查询中使用。

工作在 10 克;我不知道其他版本。

绑定变量是 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 子句?

于 2016-06-11T17:38:42.133 回答
-2

Select Into 功能仅适用于 PL/SQL Block,当您使用 Execute immediate 时,oracle 将 v_query_str 解释为 SQL Query 字符串,因此您不能使用 into 。将获得关键字丢失异常。在示例 2 中,我们使用 begin end;所以它变成了 pl/sql 块并且它是合法的。

于 2016-12-27T11:34:40.333 回答