过程:PL/SQL: ORA-00904: "QUARTER": 无效标识符

Procedure: PL/SQL: ORA-00904: "QUARTER": invalid identifier

我是 Oracle PL/SQL 的新手,我正在尝试创建一个名为 pop_date_dim 的过程,该过程填充一个名为 date_dim 的已存在的日期维度。它通过接受日期 (DDMMYYYY) 和数字 (n) 作为参数来实现。然后使用 FOR 循环填充日期维度。不幸的是,我不断收到两个错误。错误(142,9):PL/SQL:SQL 语句忽略和错误(152,13):PL/SQL:ORA-00904:“QUARTER”:无效标识符。

这是代码:

CREATE OR REPLACE PROCEDURE pop_date_dim (DDMMYYYY IN number, n IN number)
IS 
start_date date;
BEGIN
start_date := TO_DATE(DDMMYYYY, 'DDMMYYYY');
    FOR i IN 1..n LOOP
        INSERT INTO date_dim
            VALUES ( 
            start_date + i, 
            dayofweek(start_date + i), 
            dayofmonth(start_date + i), 
            dayofyear(start_date + i),
            dayname(start_date + i),
            month(start_date + i),
            monthname(start_date + i) + i,
            year(start_date + i),
            quarter(start_date + i)
            ); 
    END LOOP;
END;

这似乎与Oracle 的quarter() 函数有关,它应该return 一个1 到4 范围内的整数。我根本看不出问题是什么。有什么建议或指点吗?

None 使用的函数是 Oracle 函数内置的,它们可能是用户定义的,但 Oracle 确实提供了 to_char(some_date,'fmt'),其中 fmt 代码可以提供您需要的每个值,包括 quarter。参见 to_char。此外,无需遍历日期。您可以通过单个语句来执行此操作,也可以将其构建到过程中。

create or replace procedure pop_date_dim(
                            start_date     in date
                          , number_of_days in number
                          )
is    
begin 
     insert into date_dim(
                <list of columns> 
               ) 
     with date_list (each_date) as 
          ( select start_date + (level-1) 
              from dual connect by level <= number_of_days
          ) 
    select <list of values> 
      from date_list;
end pop_date_dim; 

参见 demo。 demo只做了部分字段,应该足以展示过程了。

所有这些函数,大概来自 MySQL 数据库,在 VALUES 列表中不存在于 Oracle 数据库中,应该被翻译。

确实不需要用这些转换后的值填充 table 的列,因为您可以通过对 [=] 中的每个值使用 suitable TO_CHAR() 转换来获取它们24=] 语句,但为了您的情况,考虑到 Oracle DB

可能会重写该过程
CREATE OR REPLACE PROCEDURE pop_date_dim(DDMMYYYY IN VARCHAR2, n IN INT) IS
  start_date DATE;
BEGIN
  start_date := TO_DATE(DDMMYYYY, 'DDMMYYYY');
  FOR i IN 1 .. n LOOP
    INSERT INTO date_dim
    VALUES
      (start_date + i,
       TO_CHAR(start_date + i, 'D', 'NLS_DATE_LANGUAGE=English'),
       TO_CHAR(start_date + i, 'DD'),
       TO_CHAR(start_date + i, 'DDD'),
       TO_CHAR(start_date + i, 'Day', 'NLS_DATE_LANGUAGE=English'),
       TO_CHAR(start_date + i, 'MM'),
       TO_CHAR(start_date + i, 'Month', 'NLS_DATE_LANGUAGE=English'),
       TO_CHAR(start_date + i, 'YYYY'),
       TO_CHAR(start_date + i, 'Q'));
  END LOOP;
END;
/

你应该将第一个参数设置为字符串类型而不是数字类型,以防止该值具有前导零的情况

Demo