PL/SQL 脚本验证

Posted

技术标签:

【中文标题】PL/SQL 脚本验证【英文标题】:PL/SQL Script verification 【发布时间】:2013-05-10 09:23:52 【问题描述】:

我有一个日期列。现在我的任务是创建一个 udf。此 UDF 的基本目的是检查日期的年份。这是在 ORACLE 中。

如果年份小于 1753,则将年份指定为 1753 并返回日期。

例如:

1) select xyz_fun('1800-01-01') from a_table => Return 1800 - 01 -01
2) select xyz_fun('1600-01-01') from a_table => Return 1753 - 01 -01
3) select xyz_fun('0001-01-01') from a_table => Return 1753 - 01 -01

返回值应该是日期。

我写了一个 UDF,但它返回警告,虽然没有显示警告。

create or replace function someschema.change_date(date1 in date) return date
;

begin
  if( extract(year from date1) < 1753 )
    then
      return to_date('1753'||'-'|| to_char(date1,'MM')||'-'|| to_char(date1,'dd'),'yyyy-MM-dd');
    else
    return date1;
    end if;

end;

【问题讨论】:

考虑简化你的表达式,也许是:to_date('1753'||to_char(date1,'-MM-dd'),'yyyy-MM-dd') 【参考方案1】:

您可以在 SQL*Plus 中发出“显示错误”来查看错误。

但你不应该在第一行的末尾有分号,它应该有asis

create or replace function someschema.change_date(date1 in date) return date as
begin
  if( extract(year from date1) < 1753 )
    then
      return to_date('1753'||'-'|| to_char(date1,'MM')||'-'|| to_char(date1,'dd'),'yyyy-MM-dd');
    else
      return date1;
    end if;
end;
/

您所做的与您所说的不太相符;您保留原始日期的月份和日期,这似乎很奇怪。如果您确实想要 1753-01-01,那么您可以使用 ANSI 日期文字:

     return date '1753-01-01';

要处理闰年(根据评论),您可以使用add_months 和年份差异来执行类似的操作,假设您很高兴将02-29 调整为02-28(并且还简化了有点像大卫的回答):

create or replace function change_date(date1 in date) return date as
begin
    return greatest(date1,
        add_months(date1, 12 * (1753 - extract(year from date1))));
end;
/

alter session set nls_date_format = 'YYYY-MM-DD';
select change_date(date '1600-02-29') from dual;

CHANGE_DAT
----------
1753-02-28

【讨论】:

@Prashanth - 顺便说一句,如果您要保留月份和日期,则需要以某种方式处理闰年。 select change_date(date '1600-02-29') from dual 将抛出 ORA-01839: date not valid for month specified,因为 1753-02-29 不是有效日期。 是的..我刚刚面对它..谢谢.. :) @Prashanth - 我添加了一个使用add_months 调整年份的版本,而不是仅仅强制它,它会针对闰年进行调整......在这个过程中损失了一天,但这可能是一个小问题考虑...【参考方案2】:

将数据传递到早期版本的 SQL Server 是否存在问题,它不存储 1753 年之前的日期?还是公历问题(Oracle 可以处理)?

无论如何,您可能想在纯 SQL 以及 PL/SQL 方法中尝试这个:

to_date(to_char(greatest(1753,to_number(to_char(my_date,'yyyy'))),'fm0000')||to_char(my_date,'-MM-dd'),'yyyy-mm-dd')

【讨论】:

不应该是greatest吗?

以上是关于PL/SQL 脚本验证的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL:是不是有完全停止脚本执行的指令?

从 PL/SQL 中的过程返回值数组

PL/SQL 中的验证检查

在 PL/SQL 中验证 IBAN

在 PL/SQL 中捕获 SQL/开发人员脚本输出

JDBC:调用外部 SQL 脚本,它声明一个 PL/SQL 包