代码之家  ›  专栏  ›  技术社区  ›  Caims

在过程中声明变量和select语句

  •  0
  • Caims  · 技术社区  · 8 年前

    我正在编写一个SQL过程,它应该使用存储为select语句中局部变量的计算日期。我正在使用Oracle SQL developer。我的代码是:

    create or replace PROCEDURE 
                                       my_procedure
    AS
    BEGIN
    DECLARE
      l_max_dt  DATE;
    BEGIN
     SELECT MAX(TRX_DT)
     INTO   l_max_dt
     FROM   TABLE
     WHERE 1=1;
    end;
     select * from TABLE where trx_dt = l_max_dt;
    end;
    

    这段代码给了我一个错误:“error(14,48):PL/SQL:ORA-00904:“L\u MAX\u DT”:存在select语句时的无效标识符”。 如何存储变量以在语句中使用它们?

    2 回复  |  直到 8 年前
        1
  •  0
  •   XING    8 年前

    这就是你写一个 Procedure . Syntax incorrect . 了解语法 Here

    CREATE OR REPLACE PROCEDURE my_procedure
    AS
       l_max_dt   DATE;
       v_var      TABLE2%ROWTYPE;
    BEGIN
       SELECT MAX (TRX_DT)
         INTO l_max_dt
         FROM TABLE1
        WHERE 1 = 1;
    
       -- Assuming the query will retrun only 1 row. 
       SELECT *
         INTO v_var
         FROM TABLE2
        WHERE trx_dt = l_max_dt;
    END;
    
        2
  •  0
  •   Boneist    8 年前

    你的问题是范围问题。在您的过程中,有一个嵌套块,在其中声明l\u max\u dt变量。一旦代码退出该块,l\u max\u dt变量就不再在范围内,即外部块对其一无所知。

    在此实例中不需要嵌套块-您可以在同一块中完成所有操作,如下所示:

    create or replace PROCEDURE my_procedure
    AS
      l_max_dt  DATE;
    BEGIN
      SELECT MAX(TRX_DT)
      INTO   l_max_dt
      FROM   TABLE
      WHERE 1=1;
    
    --  commented out as this isn't valid syntax; there is a missing INTO clause
    --  select *
    --  from TABLE where trx_dt = l_max_dt;
    END my_procedure;
    

    然而,您可以简单地一次性完成查询-例如:

    select *
    from   your_table
    where  trx_dt = (select max(trx_dt) from your_table);
    

    关于您的程序有两点:

    1. 在PL/SQL中,如果使用隐式游标(即,当您将select语句直接放入代码体中时),则需要将结果放入其中。您可以将结果批量收集到一个数组中,也可以确保只将一行(或针对未找到任何数据和太多行的代码错误处理)接收到一个记录或相应的标量变量中。
    2. 你不应该使用 select * 相反,在您的过程中,您应该显式地声明返回的列,因为有人向该表中添加列可能会导致您的过程出错。这条“规则”也有例外,但明确说明列是一个好习惯。