SQL列名与PL / SQL变量名相同 - 如何在select语句中完成?

时间:2016-04-14 15:15:22

标签: oracle plsql

假设我有一张桌子:

create table foo (
  col_1     number;
  col_2     number;
);

然后我有以下代码

declare
   col_1    number;
   col_2    number;
begin
   col_1 := 1;
   select col_2 into col_2 from foo where col_1 = col_1;
end;

当然这不会按预期工作。如何在不需要更改变量名称的情况下使其工作?

5 个答案:

答案 0 :(得分:4)

如果您对"的定义足够自由,您可以,而无需更改变量名称" 。阅读精彩的PL/SQL Name Resolution说:

  

如果在命名的PL / SQL单元中声明了标识符,则可以使用以下语法限定其简单名称(其声明中的名称)和单元名称(块,子程序或包):

     

unit_name.simple_identifier_name

以下示例将按预期打印20

create table foo (a number, b number);

insert into foo values(1, 10);
insert into foo values(2, 20);
insert into foo values(3, 30);

begin
  <<bar>>
  declare
    a number;
    b number;
  begin
    a := 2;
    select b into bar.b from foo where a = bar.a;
    dbms_output.put_line(b);
  end;
end;
/

不更改变量名称。相反,他们是嗯...更合格:))

请注意以下内容无效:

begin
  declare
    a number;
    b number;
  begin
    a := 2;
    select foo.b into b from foo where foo.a = a;
    dbms_output.put_line(b);
  end;
end;
/

由于precedence rules,因此a - 语句中的非限定select被解释为列:

  

如果SQL语句引用既属于列又属于局部变量或形式参数的名称,则列名优先。

答案 1 :(得分:1)

您可以使用带有EXECUTE IMMEDIATE:

的dinamic查询
declare
   col_1    number;
   col_2    number;
begin
   col_1 := 2;
   execute immediate 'select col_2 from foo where col_1 = :a'
   into col_2
   using col_1;   
end;

答案 2 :(得分:0)

为了将来参考并携带一个来自@ user272735的答案 - 以下内容也适用

create table foo (a number, b number);

insert into foo values(1, 10);
insert into foo values(2, 20);
insert into foo values(3, 30);
/

create procedure bar
as
  a number;
  b number;
begin
  a := 2;
  select b into bar.b from foo where a = bar.a;
  dbms_output.put_line(b);
end;
/

答案 3 :(得分:0)

为了完整起见,我还没有看到另外一个变种:

<<mytest>>
declare
   dummy dual.dummy%type := '?';
begin
   select count(*) into :result from dual d where d.dummy = mytest.dummy;
end;

这与user272735的答案相同,但没有一层包装。

(注意并非所有客户都支持此功能,例如PL / SQL Developer 11.1在测试窗口中支持它,但在SQL或命令窗口中不支持。)

答案 4 :(得分:-1)

试试这个:

   declare
       col_1    number;
       col_2    number;
    begin
       col_1 := 1;
       select foo.col_2 into col_2 from foo where foo.col_1 = col_1;

       dbms_output.put_line(col_2);

    end;
/

表名或同义词表示它实体链接到表。 如果您执行过程名称,也可以使用过程名称。

例如,如果proc名称为DO,则可以执行以下操作:

   select foo.col_2 into DO.col_2 from foo where foo.col_1 = DO.col_1;