在 PL/SQL 中将绑定变量与动态 SELECT INTO 子句结合使用

发布于 2024-12-10 19:36:50 字数 1152 浏览 0 评论 0原文

我有一个关于 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;
/

我想知道是否可以在这样的 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 语句作为动态字符串,并在 INTO 子句中使用绑定变量。

我目前正在旅行,几天之内无法使用家里的计算机,但这已经困扰了我一段时间。尝试阅读 PL/SQL 参考,但他们没有这样的选择示例。

谢谢

I have a question regarding where bind variables can be used in a dynamic SQL statement in PL/SQL.

For example, I know that this is valid:

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

I was wondering if you could use a bind variables in a select statement like this

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

Note I used a SELECT INTO statement as my dyamic string and used a bind variable in the INTO clause.

I am currently travelling right now and won't have access to my computer back at home for a few days, but this has been nagging me for a bit. Tried reading the PL/SQL reference but they don't have an example of a select like this.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

活泼老夫 2024-12-17 19:36:50

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

EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;

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

In my opinion, a dynamic PL/SQL block is somewhat obscure. While is very flexible, is also hard to tune, hard to debug and hard to figure out what's up.
My vote goes to your first option,

EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;

Both uses bind variables, but first, for me, is more redeable and tuneable than @jonearles option.

时光礼记 2024-12-17 19:36:50

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

SELECT COUNT(*) INTO  FROM emp_...

因为 EXECUTE IMMEDIATEv_num_of_employees 的值为 null

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

编辑

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

No you can't use bind variables that way. In your second example :into_bind in v_query_str is just a placeholder for value of variable v_num_of_employees. Your select into statement will turn into something like:

SELECT COUNT(*) INTO  FROM emp_...

because the value of v_num_of_employees is null at EXECUTE IMMEDIATE.

Your first example presents the correct way to bind the return value to a variable.

Edit

The original poster has edited the second code block that I'm referring in my answer to use OUT parameter mode for v_num_of_employees instead of the default IN mode. This modification makes the both examples functionally equivalent.

青丝拂面 2024-12-17 19:36:50

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

Put the select statement in a dynamic PL/SQL block.

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;
/
瞳孔里扚悲伤 2024-12-17 19:36:50

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

10g 即可工作;我不知道其他版本。

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

Bind variable can be used in Oracle SQL query with "in" clause.

Works in 10g; I don't know about other versions.

Bind variable is varchar up to 4000 characters.

Example: Bind variable containing comma-separated list of values, e.g.

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

(Same info as I posted here: How do you specify IN clause in a dynamic query using a variable? )

笑叹一世浮沉 2024-12-17 19:36:50

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

Select Into functionality only works for PL/SQL Block, when you use Execute immediate , oracle interprets v_query_str as a SQL Query string so you can not use into .will get keyword missing Exception.
in example 2 ,we are using begin end; so it became pl/sql block and its legal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文