Oracle SQL:声明要在查询中使用的变量&子查询

时间:2016-03-16 14:03:03

标签: sql oracle variable-declaration

我对这个Oracle数据库有些新意,并且我继承了一个包含多个子查询的大型查询。我想通过在查询中声明一些变量以便稍后参考来优化它,但我似乎无法做到正确。

这是我的查询的一个非常愚蠢的版本,如果我能以正确的格式得到它,我想我可以使完整版本工作:

DECLARE
  outage_start_time INTEGER := 1456894800;
  outage_end_time INTEGER := 1457586000;
  DST_offset INTEGER := 0;
  time_zone_offset INTEGER := 4;
BEGIN
  WITH subquery AS (
  SELECT DISTINCT
    mytable.tickets AS "TicketID"
  FROM mytable
  WHERE
    mytable_start_time >= outage_start_time AND
    mytable_end_time < outage_end_time
  )
  SELECT DISTINCT
    subquery."TicketID" AS "Ticket ID",
    TO_CHAR(TO_DATE('1970/01/01 00:00:00','YYYY/MM/DD HH24:MI:SS')+(mytable.start_time/((60*60)*24)-(time_zone_offset + DST_offset)/24),'MM/DD/YYYY HH:MI:SS PM') AS "Outage Start",
    TO_CHAR(TO_DATE('1970/01/01 00:00:00','YYYY/MM/DD HH24:MI:SS')+(mytable.end_time/((60*60)*24)-(time_zone_offset + DST_offset)/24), 'MM/DD/YYYY HH:MI:SS PM') AS "Outage End"
    --other stuff
  FROM mytable
  LEFT OUTER JOIN subquery ON mytable.tickets = subquery."TicketID"
  ;
END;

我得到的错误是:

Error starting at line : 1 in command -
DECLARE
  outage_start_time INTEGER := 1456894800;
  outage_end_time INTEGER := 1457586000;
  DST_offset INTEGER := 0;
  time_zone_offset INTEGER := 4;
BEGIN
  WITH subquery AS (
  SELECT DISTINCT
    mytable.tickets AS "TicketID"
  FROM T528
  WHERE
    mytable.start_time >= outage_start_time AND
    mytable.end_time < outage_end_time
  )
  SELECT DISTINCT
    subquery."TicketID" AS "Ticket ID",
    TO_CHAR(TO_DATE('1970/01/01 00:00:00','YYYY/MM/DD HH24:MI:SS')+(mytable.start_time/((60*60)*24)-(time_zone_offset + DST_offset)/24), 'MM/DD/YYYY HH:MI:SS PM') AS "Outage Start",
    TO_CHAR(TO_DATE('1970/01/01 00:00:00','YYYY/MM/DD HH24:MI:SS')+(mytable.end_time/((60*60)*24)-(time_zone_offset + DST_offset)/24), 'MM/DD/YYYY HH:MI:SS PM') AS "Outage End"
    --other stuff
  FROM T528
  LEFT OUTER JOIN subquery ON mytable.tickets = subquery."TicketID"
  ;
END;
Error report -
ORA-06550: line 7, column 3:
PLS-00428: an INTO clause is expected in this SELECT statement
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

看起来我的错误出现在第1行和第7行,所以我显然不知道如何正确地写这个。一点帮助将非常感激。谢谢!

1 个答案:

答案 0 :(得分:3)

您需要一个INTO子句来说明要获取查询结果的变量:

SELECT DISTINCT
    subquery."TicketID" AS "Ticket ID",
    TO_CHAR(TO_DATE('1970/01/01 00:00:00','YYYY/MM/DD HH24:MI:SS')+(mytable.start_time/((60*60)*24)-(time_zone_offset + DST_offset)/24), 'MM/DD/YYYY HH:MI:SS PM') AS "Outage Start",
    TO_CHAR(TO_DATE('1970/01/01 00:00:00','YYYY/MM/DD HH24:MI:SS')+(mytable.end_time/((60*60)*24)-(time_zone_offset + DST_offset)/24), 'MM/DD/YYYY HH:MI:SS PM') AS "Outage End"
    --other stuff
INTO variable1, variable2, ...
  FROM T528

因此,为需要获取的每个列定义一个变量,并使用相应的类型,并添加INTO子句以在变量中获取查询结果。

如果您的查询只返回一行,将值提取为标量变量,则上述解决方案效果很好。 如果您的查询返回多行,则需要一些数组变量来处理所有值;获取它的一种方法可能是:

  • 将类型定义为数组;你可能需要数组,varchar2, ...,取决于所提取列的类型
  • 为您需要提取的每个列定义一个变量
  • 添加一个BULK COLLECT INTO子句,说它可以大量获取所有内容 行进入数组变量

在声明之后,您将使用查询的结果集填充数组变量

例如:

declare
  type tyTabNuber is table of number index by pls_integer;
  type ty...
  --
  vTabNumber tyTabNumber;
  ...
begin
  select ...
  BULK COLLECT INTO vTabNumber, ...
  FROM ...
  ...
end