如何将以下T-SQL语句转换为PL / SQL
set @disbursement_no = (select isnull(max(convert(numeric, right(DV_NO, 6))), 0) + 1
from CD_T_DV_HDR where year(DATE_DV) = year(getdate()))
DV_NO
的数据类型为varchar,Date_Dv
为日期。
我是PL / SQL的新手,我很难将我的SQL语句转换为PL / SQL。我希望你能帮助我。
答案 0 :(得分:4)
就像这样:
DECLARE
disbursement_no NUMBER;
BEGIN
SELECT ( coalesce(MAX(To_number(Substr(dv_no, -6, 6))), 0) ) + 1
INTO disbursement_no
FROM cd_t_dv_hdr
WHERE To_char(date_dv, 'rrrr') = To_char(SYSDATE, 'rrrr');
END;
Substr
(dv_no, -6, 6)
获取最右边的6个字符。 to_number
将字符串转换为数字。 max
获取最大数量& coalesce
检查结果数字是否为空&将其转换为零。
答案 1 :(得分:0)
关于@Sathya评论的一件事: 如果DATE_DV被索引/用作分区键列,Oracle将不使用索引/分区,因为您在列上有一个函数。 这将导致整个表上的全表扫描不好。
你有两个选择: 1.在90%的情况下更改索引/分区以使用函数-bad idea 2.在你之间使用条件
SELECT ( coalesce(MAX(To_number(Substr(dv_no, -6, 6))), 0) ) + 1
INTO disbursement_no
FROM cd_t_dv_hdr
WHERE date_dv between trunc(sysdate,'rrrr') and trunc(add_months(sysdate,12),'rrrr')
答案 2 :(得分:-1)
DECLARE
disbursement_no int;
BEGIN
select (case when DV_NO is null 0 else max(to_number(right(DV_NO,6),'999999')) end)+1 into disbursement_no
from CD_T_DV_HDR
where extract(year from DATE_DV) = extract(year from current_date);
END;
我认为这几乎就是这样。我确定还有其他方法,postgresql中可能有一个等效的isnull(),但是如果有的话我不知道。显然你需要剩下的功能,包括一些返回等。
值得注意的是,PostgreSQL中的文本类型比其他系统中的文本类型更智能,并且varchar通常可以替换为文本,除非有特殊注意事项。
此外,如果这是一个频繁的查询,您可以在where子句上创建索引:
create index my_year_index on CD_T_DV_HDR (extract(year from DATE_DV));
这是PostgreSQL的一个非常好的功能:基于表达式创建索引。