将T-SQL转换为PL / SQL

时间:2012-02-28 00:18:40

标签: oracle tsql plsql

如何将以下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。我希望你能帮助我。

3 个答案:

答案 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的一个非常好的功能:基于表达式创建索引。