SQL column name same as PL/SQL variable name - How can this be done in a select statement?

后端 未结 5 1373
隐瞒了意图╮
隐瞒了意图╮ 2020-12-19 20:10

Suppose I have a table:

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

Then I have the following code

declar         


        
相关标签:
5条回答
  • 2020-12-19 20:25

    You can if you're liberal enough of your definition of "without the need to change the variable names". Reading the fabulous PL/SQL Name Resolution says:

    If an identifier is declared in a named PL/SQL unit, you can qualify its simple name (the name in its declaration) with the name of the unit (block, subprogram, or package), using this syntax:

    unit_name.simple_identifier_name

    The following example will print 20 as expected:

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

    Variable names are not changed. Instead they are hmm ... more qualified :)

    Note the following doesn't work:

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

    As the non-qualified a in the select-statement is interpreted as a column because of the precedence rules:

    If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.

    0 讨论(0)
  • 2020-12-19 20:26

    For completeness, there is one more variation I haven't seen mentioned yet:

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

    This is the same as user272735's answer but without a layer of wrapping.

    (Note not all clients may support this, e.g. PL/SQL Developer 11.1 supports it in Test windows but not in SQL or Command windows.)

    0 讨论(0)
  • 2020-12-19 20:31

    Try this:

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

    Table name or synonym says that it entity linked to the table. Also you can use procedure name, if you do the procedure name.

    for example, if proc name is DO, you can do the following:

       select foo.col_2 into DO.col_2 from foo where foo.col_1 = DO.col_1;
    
    0 讨论(0)
  • 2020-12-19 20:32

    You can use dinamic query with EXECUTE IMMEDIATE:

    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;
    
    0 讨论(0)
  • 2020-12-19 20:36

    For future reference and carrying one from @user272735 answer - the following also works

    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;
    /
    
    0 讨论(0)
提交回复
热议问题