在过程中声明变量和选择语句

Posted

技术标签:

【中文标题】在过程中声明变量和选择语句【英文标题】: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”:存在选择语句时的标识符无效。 如何存储变量以在语句中使用它们?

【问题讨论】:

【参考方案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);

关于您的程序的几点:

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

【讨论】:

以上是关于在过程中声明变量和选择语句的主要内容,如果未能解决你的问题,请参考以下文章

如何在存储过程的IF语句中从变量(表)中选择*

声明的表变量上的动态 Select 语句 - SYBASE

如何在 MySQL 的同一语句中声明变量?

何时选择变量来声明为最终静态

MYSQL,使用单个选择语句在存储过程中设置两个变量

Oracle 声明变量并在另一个选择查询中使用它