PLS00215:字符串长度约束必须在范围内 (1..32767)

PLS00215: String length constraints must be in range (1..32767)

我是 pl/sql 的新手。我想创建一个具有三个参数的过程,分别称为 'startMonth'、'endMonth'、'thirdMonth'。在该过程中,我正在执行一个 sql 查询,该查询位于 table_query 的 'run_sql' 列中。此查询需要 'startMonth'、'endMonth'、'thirdMonth' 的值。我就是这样写程序的。我的计划是将所有 sql 查询放在一个单独的 table 中,并在过程中的 for 循环中执行。我正在创建一个名为 table1 的 table,下个月我想删除它并再次创建 table。我是这样写程序的。

CREATE OR REPLACE procedure schema.sixMonthAverage (startMonth varchar,endMonth varchar ,thirdMonth varchar )
IS
start_date varchar := startMonth;
end_date varchar := endMonth;
begin
for c_rec in(select run_sql from table_query)
 loop
 dbms_output.put_line(startmonth);
 dbms_output.put_line(endmonth);
      execute immediate c_rec.run_sql using start_date, end_date;
      Execute IMMEDIATE 'commit';
 END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Exception');
END;

这是 table_query 中 run_sql 列中的查询。

create table table1
as
select account_num,bill_seq,bill_version,
to_char(start_of_bill_dtm,''YYYYMM-DD'') st_bill_dtm, 
to_char(bill_dtm - 1,''YYYYMM-DD'') en_bill_dtm,
to_char(actual_bill_dtm,''YYYYMM-DD'') act_bill_dtm, 
round((invoice_net_mny + invoice_tax_mny)/1000,0) mon_bill,
bill_type_id,bill_status
from billsummary
where to_char(bill_dtm - 1,''YYYYMM'') between'||chr(32)||
startMonth ||chr(32)||'and'|| chr(32)||endMonth ||chr(32)||
'and cancellation_dtm is null;

但是,当我尝试编译该过程时,出现错误“PLS00215:字符串长度约束必须在范围 (1..32767) 内”。虽然我搜索了错误,但我找不到确切的原因。这似乎是变量分配的问题。但是我无法解决。

--更新

正如答案中给出的那样,我将字符串转换为日期。

CREATE OR REPLACE procedure REPO.sixMonthAverage (startMonth varchar2,endMonth varchar2 ,thirdMonth varchar2 )
IS
start_date date := TO_DATE(startMonth, 'yyyymm');
end_date date := TO_DATE(endMonth, 'yyyymm');

但是在执行查询时,它给出了错误消息 ORA-00904:“END_DATE”:无效标识符。但它没有显示 start_date 的任何错误消息,出现此错误消息的原因是什么?

该错误指出了问题所在。字符串声明(char、varchar、varchar2——但你应该只使用 varchar2,而不是 varchar)需要一个长度;例如:

CREATE OR REPLACE procedure sixMonthAverage (startMonth varchar2,endMonth varchar2 ,thirdMonth varchar2 )
IS
start_date varchar2(10) := startMonth;
end_date varchar2(10) := endMonth;
...

注意过程参数指定长度;只有局部变量声明。

如果那些代表日期,那么它们和传入的参数可能应该是日期,而不是字符串。不过,这取决于您的动态 SQL 期望的内容 - 如果将字符串转换为日期并指定格式掩码,那么我想没问题;否则你应该传递日期,或将字符串转换为日期。不过,您展示的示例似乎没有任何绑定变量可供填充。

删除并重新创建 tables 通常不是您想要做的事情。您可以 delete/truncate 并重新填充 table;如果要保留超过一个月,则使用分区;或使用视图(或物化视图)。