在Oracle中使用DBMS_RANDOM生成随机日期

15

我有这个匿名的块:

DECLARE
   V_DATA   DATE;
BEGIN
   V_DATA := '01-GEN-2000';

   HR.STATISTICHE.RATINGOPERATORI (V_DATA);
   COMMIT;
END;

但我希望能以随机方式生成日期。我该怎么做?


在什么范围内生成随机日期?是否接受任何有效的日期值,以便您生成的大部分日期为公元前,而相对较少的日期为20世纪或21世纪?您是否希望时间组件也是随机的,还是像示例中一样将日期设置为午夜? - Justin Cave
没错!例如从2000年1月1日开始的随机日期。这是可能的吗? - sharkbait
时间组件可以是随机的。没问题。我只对日期感兴趣。 - sharkbait
1
好的。这回答了范围下限。那么范围上限是多少?或者您希望值一直到公元9999年12月31日? - Justin Cave
上限并不重要。 - sharkbait
5个回答

32

您可以生成两个日期之间的随机日期,如下所示查询。随机日期生成在2000年1月1日至9999年12月31日之间。


  SELECT TO_DATE(
              TRUNC(
                   DBMS_RANDOM.VALUE(TO_CHAR(DATE '2000-01-01','J')
                                    ,TO_CHAR(DATE '9999-12-31','J')
                                    )
                    ),'J'
               ) FROM DUAL;

或者你可以使用

SELECT TO_DATE (
              TRUNC (
                     DBMS_RANDOM.VALUE (2451545, 5373484) 
                    )
                , 'J'
              )
  FROM DUAL
在上面的示例中,第一个值是01-Jan-2000,第二个值为31-Dec-9999。

当我编译时,我遇到了这个错误:ORA-01843: 无效的月份 ORA-06512: 第4行。这意味着月份无效。 - sharkbait
+1.. 我编辑了第一个示例,明确指定日期格式掩码,这将使其在不考虑 NLS 设置的情况下工作。我想这就是 @sharkbait 出现 ORA-01843 错误的原因。 - Craig
1
我用 ANSI 日期字面量替换了 TO_DATE。这样更简短,避免了许多可能出现的 TO_DATE 问题。 - Jon Heller

6
要生成随机日期,您可以使用:
select to_date('2010-01-01', 'yyyy-mm-dd')+trunc(dbms_random.value(1,1000)) from dual

或者用于随机日期时间。
select to_date('2010-01-01', 'yyyy-mm-dd')+dbms_random.value(1,1000) from dual

0
如果你想看它的逻辑,你也可以使用这段代码。
  create or replace procedure genDate(result out nvarchar2) IS
  year  number;
  month  number;
  day  number;
Begin
  year:=FLOOR(DBMS_RANDOM.value(2000,2100));
  month:=FLOOR(DBMS_RANDOM.value(1,12));
  IF month=2 and (year/4)=0 and (year/100)!=0 then
    day:=FLOOR(DBMS_RANDOM.value(1,29));
  ELSIF month=2 or (year/100)=0 then
    day:=FLOOR(DBMS_RANDOM.value(1,28));
  ELSIF MOD(month,2)=1 then
    day:=FLOOR(DBMS_RANDOM.value(1,31));
  ELSIF MOD(month,2)=0 and month!=2 then
    day:=FLOOR(DBMS_RANDOM.value(1,30));
  END IF;  
  result:=month||'-'||day||'-'||year;
End;

0
我需要生成员工数据进行测试。每个员工都需要一个出生日期,使他们的年龄在16岁到65岁之间,并且入职日期在他们的16岁生日和SYSDATE之间。以下是具体步骤...
FUNCTION randomDateInRange(alpha IN DATE, omega IN DATE) RETURN DATE IS
BEGIN
    RETURN alpha + DBMS_RANDOM.VALUE(0, omega - alpha);
END;

...然后,使用这个函数...

-- an employee can be any age from 16 to 65 years of age
DoB := randomDateInRange(
    SYSDATE - INTERVAL '65' YEAR,
    SYSDATE - INTERVAL '16' YEAR
);

-- an employee could have been hired any date since their sixteenth birthday
DoH := randomDateInRange(
    DoB + INTERVAL '16' YEAR,
    SYSDATE
);

0

这里还有一种选项可以生成从现在开始往前推的日期,即从今天开始往前移动365天的数量,使用'DD.MM.YYYY'格式。

to_char(sysdate-dbms_random.value()*365, 'DD.MM.YYYY')


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接