【问题标题】:Declaring variables and select statement in a procedure在过程中声明变量和选择语句
【发布时间】:2017-11-14 10:20:10
【问题描述】:

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

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;

此代码给我一个错误:“错误(14,48):PL/SQL:ORA-00904:“L_MAX_DT”:存在选择语句时的标识符无效。 如何存储变量以在语句中使用它们?

【问题讨论】:

    标签: sql plsql oracle-sqldeveloper


    【解决方案1】:

    这就是您编写Procedure 的方式。 Syntaxincorrect。阅读语法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;
    

    【讨论】:

    • 如何使用带有 l_max_dt 的 select 语句?
    【解决方案2】:

    您的问题是范围之一。在您的过程中,您有一个嵌套块,您可以在其中声明 l_max_dt 变量。一旦代码退出该块,l_max_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 语句直接放在代码主体中时),您需要有一些东西可以将结果放入其中。您可以将结果批量收集到一个数组中,或者您可以确保将一行(或 NO_DATA_FOUND 和 TOO_MANY_ROWS 的代码错误处理)准确地接收到记录或相应的标量变量中。
    2. 您不应该在您的过程中使用select * - 相反,您应该明确声明要返回的列,因为向该表添加列的人可能会导致您的过程出错。这个“规则”也有例外,但明确说明列是一个好习惯。

    【讨论】:

      猜你喜欢
      • 2023-03-11
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-16
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多