【问题标题】:Why am I being prompted for a variable which I already defined?为什么提示我输入已定义的变量?
【发布时间】:2016-06-07 08:23:57
【问题描述】:

所以,我是使用 PL/SQL 的新手。我已经定义了一个名为 startDate 的变量,然后我想稍后在某些查询中引用它。但是,当我稍后使用 &&startDate 引用它时,系统会提示我输入变量。

/* Define the date bounds used */
/* Depending on the current quarter I want to set my start and end dates differently */
DROP TABLE DATE_BOUNDS;
CREATE TABLE DATE_BOUNDS AS
select
      case    when to_char(sysdate, 'Q') = '1' then to_date('10/01' || to_char(to_char(sysdate, 'YYYY')-1))
                  when to_char(sysdate, 'Q') = '2' then to_date('01/01/' || to_char(sysdate, 'YYYY'))     
                  when to_char(sysdate, 'Q') = '3' then to_date('04/01/' || to_char(sysdate, 'YYYY'))
                  when to_char(sysdate, 'Q') = '4' then to_date('07/01/' || to_char(sysdate, 'YYYY'))
      end as date1,
      case    when to_char(sysdate, 'Q') = '1' then add_months(to_date('10/01' || to_char(to_char(sysdate, 'YYYY')-1))-1,12)
                  when to_char(sysdate, 'Q') = '2' then add_months(to_date('01/01/' || to_char(sysdate, 'YYYY'))-1    ,12) 
                  when to_char(sysdate, 'Q') = '3' then add_months(to_date('04/01/' || to_char(sysdate, 'YYYY'))-1,12)
                  when to_char(sysdate, 'Q') = '4' then add_months(to_date('07/01/' || to_char(sysdate, 'YYYY'))-1,12)
      end as date2
from dual;

/* Defining the variable 'startDate' as 'date1' from the previous table */
DECLARE 
  startDate date;
BEGIN
  SELECT date1 INTO startDate
  FROM DATE_BOUNDS;
END;

当我尝试一些简单的事情时,比如:

select &&startDate from dual;

当我在 SQL Developer 中运行它时,系统会提示我输入 startDate 而不是仅使用 supposedDECLARE 步骤中定义的内容。 . 什么给了?

【问题讨论】:

    标签: sql oracle variables dynamic


    【解决方案1】:

    您将 PL/SQL startDate 变量与 SQL*Plus 或 SQL Developer substitution variable 混淆了,该变量在您的 PL/SQL 块中声明且仅存在于其中。后者如果 defined 被客户端使用,并且可以在匿名块内使用(尽管这样做并不常见)。它们是不同范围内完全独立的变量,不可互换。

    您无法看到或引用块外的 PL/SQL 变量。如果您想要一些可以轻松参考的内容,您可以使用客户端bind variable

    var startDate varchar2(10);
    BEGIN
      SELECT to_char(date1, 'YYYY-MM-DD') INTO :startDate
      FROM DATE_BOUNDS;
    END;
    /
    
    select :startDate, to_date(:startDate, 'YYYY-MM-DD') from dual;
    

    print :startDate
    

    不过需要注意三件事。首先,引用有一个冒号:startDate,表示它是一个绑定变量;现在没有本地 PL/SQL 变量;而且你不能有日期类型,所以必须在日期之间进行转换,所以这不是最好的例子......


    如果要从查询中填充替换变量,可以使用column new_value,它也是一个客户端命令,无需任何 PL/SQL:

    column oldColName new_value newColName
    SELECT to_char(date1, 'YYYY-MM-DD') AS oldColName
    FROM DATE_BOUNDS;
    

    然后您参考&newColName

    【讨论】:

    • 有可能,但我不记得 SQLPlus 命令在 SQLPlus 中创建绑定变量。在 PL/SQL 匿名块中为该变量赋值。然后稍后使用该值绑定变量,例如select :startDate from dual。一个限制是类型受到限制,DATE 不受 SQL*Plus 支持。 (可能已经改变。)
    • 这很好用,谢谢。但是,稍后我将在 CREATE TABLE 语句中使用日期 - 正如我刚刚发现的那样,它不允许绑定变量。哦,好吧。
    • @mjavon - 我添加了一种从查询中获取值的方法,作为替换变量,然后您可以在create table 中使用它。管他呢。不过,您需要一个不同的格式掩码,没有破折号。根据日期或任何其他数据创建表听起来不是一个好的数据模型,但这是另一个问题。
    猜你喜欢
    • 2020-01-30
    • 2020-11-25
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    相关资源
    最近更新 更多