oracle中的变量和多个选择语句

Posted

技术标签:

【中文标题】oracle中的变量和多个选择语句【英文标题】:variables and multiple select statements in oracle 【发布时间】:2013-12-17 14:40:25 【问题描述】:

我正在努力使用一些 oracle sql 语法。 (我习惯用sql server)。

我尝试使用一个变量来存储一个值,以便以后再次使用该值。

但是在一个变量块中,显然我需要对查询进行选择(对我来说很奇怪),我无法获得屏幕输出。

我设法使用临时表编写了以下查询:

CREATE GLOBAL TEMPORARY TABLE temp
    (leeftijd varchar(30),
     aantal number,
     aantalProcentueel number)
  ON COMMIT DELETE ROWS;

declare 
  aantalLeden number;
begin
  select count(*) into :aantalLeden
  FROM dbcmnu_all
  WHERE     DBCMNU_ALL.ZF_VP='105' AND DBCMNU_ALL.BEGIN_ZF_VP <= sysdate AND 
          (DBCMNU_ALL.EIND_ZF_VP >= sysdate Or DBCMNU_ALL.EIND_ZF_VP Is Null) 
          AND DBCMNU_ALL.DATDEC Is Null;

select case
    when rijksnummer is null then 'ongeldig'
    when length(rijksnummer) < 6 then 'ongeldig'
    when substr(rijksnummer, 5, 2) <= 0 or  substr(rijksnummer, 5, 2) > 12 then 'ongeldig'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 0 and 9.99 then '0-9'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 10 and 19.99 then '10-19'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 20 and 29.99 then '20-29'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 30 and 39.99 then '30-39'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 40 and 49.99 then '40-49'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 50 and 59.99 then '50-59'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 60 and 69.99 then '60-69'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 70 and 79.99 then '70-79'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 80 and 89.99 then '80-89'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 90 and 99.99 then '90-99'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 >=  100              then '100+'
  end as leeftijd
  , count(*) as aantal
  into temp
FROM dbcmnu_all
WHERE   DBCMNU_ALL.ZF_VP='105' AND DBCMNU_ALL.BEGIN_ZF_VP <= sysdate AND 
        (DBCMNU_ALL.EIND_ZF_VP >= sysdate Or DBCMNU_ALL.EIND_ZF_VP Is Null) 
        AND DBCMNU_ALL.DATDEC Is Null

  group by
  case
    when rijksnummer is null then 'ongeldig'
    when length(rijksnummer) < 6 then 'ongeldig'
    when substr(rijksnummer, 5, 2) <= 0 or  substr(rijksnummer, 5, 2) > 12 then 'ongeldig'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 0 and 9.99 then '0-9'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 10 and 19.99 then '10-19'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 20 and 29.99 then '20-29'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 30 and 39.99 then '30-39'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 40 and 49.99 then '40-49'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 50 and 59.99 then '50-59'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 60 and 69.99 then '60-69'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 70 and 79.99 then '70-79'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 80 and 89.99 then '80-89'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 between 90 and 99.99 then '90-99'
    when months_between(TRUNC(sysdate),to_date(substr(rijksnummer, 1, 8), 'YYYYMMDD'))/12 >=  100              then '100+'
  end
  order by leeftijd;


end;

select leetijd, aantal, aantalProcentueel
 from temp;

此查询失败,它显示:PLS-00103: Encountered the symbol "SELECT"

现在我如何在 oracle sql 中声明一个变量并稍后在 sql 语句中使用该变量? (我想添加一列 blabla / 变量作为列名

如果可能的话,我还想在屏幕上输出...

【问题讨论】:

select into 只是将值放入变量中,您不能使用它将数据放入表中。你需要使用insert into temp (..) select .... 另外,select count(*) into :aantalLeden 中不需要冒号。请改写select count(*) into aantalLeden 只有一个补充:您可以使用select ... bulk collect into将多条记录选择到集合变量中。 你在哪里运行这个——作为一个脚本,从 SQL*Plus 或 SQL Developer 一次性运行? 感谢您的意见!我应该考虑学习oracle课程,我认为有sql server知识我可以管理,但比我预期的要难 【参考方案1】:

PLS-00103 是因为 PL/SQL 解析器试图将 select 解释为块流的一部分,它在那里无效。您需要使用/ 终止并执行该块:

declare 
  aantalLeden number;
begin
  ...
end;
/

select leetijd, aantal, aantalProcentueel
 from temp;

@a_horse_with_no_name 是对的,您应该使用insert into,而不是select into; @YaroslavShabalin 对您的额外冒号是正确的,因为 aantalLeden 是本地 PL/SQL 变量,而不是绑定变量:

select count(*) into aantalLeden
FROM dbcmnu_all
WHERE   DBCMNU_ALL.ZF_VP='105' AND DBCMNU_ALL.BEGIN_ZF_VP <= sysdate AND 
        (DBCMNU_ALL.EIND_ZF_VP >= sysdate Or DBCMNU_ALL.EIND_ZF_VP Is Null) 
        AND DBCMNU_ALL.DATDEC Is Null;

insert into temp (leeftijd, aantal number)
select case
    ...
  end as leeftijd
  , count(*) as aantal
from ...
group by ...;

在用于插入的选择中包含order by 子句没有多大意义。我不确定您打算如何处理您的 aantalLeden 值;不清楚是否要将所有行的 aantalProcentueel 值设置为该值。

不过,您可能根本不想要一个临时表,这取决于您接下来要如何处理它。

【讨论】:

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

oracle sql - 选择具有多个“case when”的语句并检查是不是包含文本

Oracle 中的非相关子选择是不是在外部语句之前计算?

Oracle 变量作为选择

在 Python 中为 Oracle 选择查询绑定变量

Oracle 12c - 插入到选择查询中的不明确列,ORA-00918

Oracle PL/SQL 在原始选择和分层选择之间切换