【问题标题】:PL/SQL Using a Variable in an Adhoc SELECTPL/SQL 在 Adhoc SELECT 中使用变量
【发布时间】:2016-04-24 03:02:58
【问题描述】:

我正在(尝试)编写一个查询,它将在查询的多个点使用相同的日期。我想使用一个变量来更轻松地运行不同日期的查询。我该怎么做?当我尝试按原样执行查询时遇到各种错误。


ORA-06550:第 25 行,第 5 列: PLS-00103:在预期以下情况之一时遇到符号“END”:


DECLARE 
    CalendarDate Date := TO_DATE('1/20/2015','MM/DD/YYYY');
BEGIN

SELECT 
    TIME_OF_DAY, COUNT(TIME_OF_DAY) ISSUE_ACTIVITY_COUNT
FROM
    (SELECT
        case 
            when to_char(CREATED_DT,'mi') between '00' and '14' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '15' minute,'HH24:MI')
            when to_char(CREATED_DT,'mi') between '15' and '29' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '30' minute,'HH24:MI')
            when to_char(CREATED_DT,'mi') between '30' and '44' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '45' minute,'HH24:MI')
            when to_char(CREATED_DT,'mi') between '45' and '59' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '60' minute,'HH24:MI')
        end as TIME_OF_DAY
    FROM
        CE.ISSUE_ITEM i
    WHERE
        (TRUNC(i.CREATED_DT) = CalendarDate))
    GROUP BY
        TIME_OF_DAY
    ORDER BY
        TIME_OF_DAY;

EXECUTE IMMEDIATE     
END;

【问题讨论】:

  • “立即执行”构造执行动态sql,您使用的语法错误。 docs.oracle.com/cd/B19306_01/appdev.102/b14261/…。您的代码的最终目标是什么?
  • 您要对过程中的 SELECT 语句做什么?正如@bdn02 所指出的,EXECUTE IMMEDIATE 是 A) 在错误的位置,并且 B) 没有必要,因为这里没有使用动态 SQL。您是否尝试在过程中的 SELECT 语句上打开一个游标并返回它?您是否尝试在查询工具中执行此 SELECT 语句并显示结果?或者是其他东西..?请编辑您的问题并添加进一步的解释。谢谢。
  • 另外,如果这是动态 SQL,您需要为内联视图设置别名。大多数 PL/SQL 不喜欢无别名的内联视图。与 t-SQL 不同的是,PL/SQL 需要创建一个 refcursor.or sysrefcursor 来返回一个记录集,我认为这就是你想要做的。stackoverflow.com/questions/2153053/…

标签: sql variables select plsql


【解决方案1】:

要在查询中多次使用日期,请使用WITH 子句:

with t as (select to_date('1/20/2015','mm/dd/yyyy') calendar_date from dual)
select t.calendar_date, <other columns>
  from CE.ISSUE_ITEM i, t
 where trunc(i.created_dt) = t.calendar_date

我希望我对您需要什么的猜测是正确的。

【讨论】:

    【解决方案2】:

    你犯的错误

    ... 与 EXECUTE IMMEDIATE 语句有关,这根本没有任何意义。我不知道你想用它做什么,所以我不会修正你的答案,而是向你展示替代方案:

    重用绑定变量

    您不需要为此使用 PL/SQL。使用普通的命名绑定变量:

    SELECT 
        TIME_OF_DAY, COUNT(TIME_OF_DAY) ISSUE_ACTIVITY_COUNT
    FROM
        (SELECT
            case 
                when to_char(CREATED_DT,'mi') between '00' and '14' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '15' minute,'HH24:MI')
                when to_char(CREATED_DT,'mi') between '15' and '29' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '30' minute,'HH24:MI')
                when to_char(CREATED_DT,'mi') between '30' and '44' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '45' minute,'HH24:MI')
                when to_char(CREATED_DT,'mi') between '45' and '59' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '60' minute,'HH24:MI')
            end as TIME_OF_DAY
        FROM
            CE.ISSUE_ITEM i
        WHERE
            (TRUNC(i.CREATED_DT) = :CalendarDate)) -- Bind variable here
        GROUP BY
            TIME_OF_DAY
        ORDER BY
            TIME_OF_DAY;
    

    然后您可以在整个 SQL 语句中重复使用该绑定变量。

    使用公用表表达式(Oracle 语言中的子查询因子)

    原则上,您可以使用以下类型的查询来为单个语句的范围引入变量:

    WITH vars (CalendarDate) AS (
        SELECT DATE '2015-01-20' FROM DUAL
    )
    SELECT 
        TIME_OF_DAY, COUNT(TIME_OF_DAY) ISSUE_ACTIVITY_COUNT
    FROM
        (SELECT
            case 
                when to_char(CREATED_DT,'mi') between '00' and '14' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '15' minute,'HH24:MI')
                when to_char(CREATED_DT,'mi') between '15' and '29' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '30' minute,'HH24:MI')
                when to_char(CREATED_DT,'mi') between '30' and '44' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '45' minute,'HH24:MI')
                when to_char(CREATED_DT,'mi') between '45' and '59' then TO_CHAR(trunc(CREATED_DT,'HH24') + interVal '60' minute,'HH24:MI')
            end as TIME_OF_DAY
        FROM
            CE.ISSUE_ITEM i CROSS JOIN vars
        WHERE
            (TRUNC(i.CREATED_DT) = vars.CalendarDate)) -- "Variable" from CTE here
        GROUP BY
            TIME_OF_DAY
        ORDER BY
            TIME_OF_DAY;
    

    不过,我个人觉得这有点晦涩难懂。为了访问变量,你必须交叉连接它们,这不是很可读。

    【讨论】:

      猜你喜欢
      • 2017-03-29
      • 1970-01-01
      • 1970-01-01
      • 2014-10-14
      • 2021-10-29
      • 2011-12-10
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多