Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Random TIMESTAMP out of range

I’m trying to create a function, which returns a random TIMESTAMP between a range of timestamps.

It doesn’t appear to be working ALL the time as sometimes I get a value back before the starting range and sometimes I get a value back after the ending range.

Below is my test CASE and example of a TIMESTAMP out of range.In this example the TIMESTAMP is after the ending range of TIMESTAMP ‘2023-01-25 12:00:00’

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Can someone please explain what the problem is and show me how to fix it as I can’t seem to figure this out.


ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'DD-MON-YYYY  HH24:MI:SS.FF';

CREATE OR REPLACE FUNCTION random_timestamp(
      p_from      IN TIMESTAMP,
      p_to        IN TIMESTAMP,
      p_fraction  IN VARCHAR2   DEFAULT 'Y'
    ) RETURN TIMESTAMP
   IS
      return_val_y TIMESTAMP     := p_from + dbms_random.value () * (p_to - p_from + INTERVAL '1' DAY);
      return_val_n TIMESTAMP (0) := return_val_y;
 BEGIN
      RETURN  CASE
                  WHEN UPPER (SUBSTR (p_fraction, 1, 1)) = 'Y'
          THEN return_val_y
          ELSE return_val_N
          END;
END random_timestamp;
/

SELECT random_timestamp( 
TIMESTAMP '2023-01-25 09:00:00', TIMESTAMP '2023-01-25 12:00:00') as ts from dual

TS
26-JAN-2023  03:59:06.013730

>Solution :

You are adding 1 day:

p_from + dbms_random.value () * (p_to - p_from + INTERVAL '1' DAY);

It falls within the range of p_from to p_to plus 1 day and is doing exactly what you told it to do.

If you don’t want the range to be 1 day extra then remove + INTERVAL '1' DAY

CREATE OR REPLACE FUNCTION random_timestamp(
  p_from      IN TIMESTAMP,
  p_to        IN TIMESTAMP,
  p_fraction  IN VARCHAR2   DEFAULT 'Y'
) RETURN TIMESTAMP
IS
  return_val_y TIMESTAMP(9) := p_from + dbms_random.value() * (p_to - p_from);
  return_val_n TIMESTAMP(0) := return_val_y;
BEGIN
  RETURN CASE
         WHEN p_fraction LIKE 'Y%' OR p_fraction LIKE 'y%'
         THEN return_val_y
         ELSE return_val_n
         END;
END random_timestamp;
/

Then:

SELECT MIN(ts),
       MAX(ts)
FROM   (
  SELECT random_timestamp(
           TIMESTAMP '2023-01-25 09:00:00',
           TIMESTAMP '2023-01-25 12:00:00'
         ) AS ts
  FROM   DUAL
  CONNECT BY LEVEL <= 1e6
);

May randomly output:

MIN(TS) MAX(TS)
25-JAN-23 09.00.00.017186000 25-JAN-23 11.59.59.999534000

And stays within the range.

fiddle

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading