Generating Random Values in pl/sql - random

I try to generate random value in pl/sql. But i need these values must be fix 12 character.
For example 654696544846, 234864687644, 438792168431
Thanks.

If you need a strictly numeric string made of decimal characters, you can use the dbms_random.value function which, when given 2 values X and Y, returns a random number between X (included) and Y (excluded)
select trunc(dbms_random.value(100000000000,1000000000000)) from dual
if you can accept also alphanumeric chars, you can use the dbms_random.string function:
select dbms_random.string('X',12) from dual
the second parameter is the required string length, the first dictates the subset of characters that are allowed in the string
'u', 'U' - uppercase alpha characters
'l', 'L' - lowercase alpha characters
'a', 'A' - mixed case alpha characters
'x', 'X' - uppercase alpha-numeric characters
'p', 'P' - any printable characters.
source: https://docs.oracle.com/database/121/ARPLS/d_random.htm

dbms_random.value returns a value between 0 and 1 with a precision of 39 digits, which you then multiply by 1000000000000 to get 12 digit number. It has a decimal part was well which can be removed with a suitable call to to_char which will also format it with a constant length.
select to_char(dbms_random.value * 1000000000000,'fm000000000000') from dual;

Related

how to trim leading zero in oracle sql from concatenation text (text:number-number-number

how to trim leading zero in oracle sql from concatenation text
(text:number-number-number)
example(word:number-number-number) word can have text or double zero
but always has char before it after word, max digits separated by '-'
all time max 3 digits i want to keep zeros in first part. and after
that if remove leading 0 in sequence but keep it if it's only one 0
MachineAbc00:1-0-03 = MachineAbc00:1-0-3
MachineAbc00:1-001-02 = MachineAbc00:1-1-2
tried many combination, not successful , like
REGEXP_REPLACE ('MachineO00:1-0-03*', '0+(?!$)', '-')
REGEXP_REPLACE ('MTROPQFMO00:1-0-03*', '(-0){1,}', '-')
If all the input strings are in the exact format you said they are, then something like this should work:
with
sample_strings (str) as (
select 'MachineAbc00:1-0-03' from dual union all
select 'MachineAbc00:1-001-02' from dual union all
select 'MachineZzzyx:200-020-002' from dual union all
select 'machineCX032:0-000-0' from dual
)
select str as old_str,
regexp_replace(str, '([:-])0*(\d+)', '\1\2') as new_str
from sample_strings
;
OLD_STR NEW_STR
------------------------ ------------------------
MachineAbc00:1-0-03 MachineAbc00:1-0-3
MachineAbc00:1-001-02 MachineAbc00:1-1-2
MachineZzzyx:200-020-002 MachineZzzyx:200-20-2
machineCX032:0-000-0 machineCX032:0-0-0
The regular expression function finds any occurrence of (colon or dash) followed by (zero or more 0 characters/digits) followed by at least one more digit. The "zero or more 0 digits" is maximal with the property that there must be at least one more digit AFTER that match (even if that extra digit hapens to be a zero - see my last test string, which I added precisely in order to test that this works correctly). The function replaces each such occurrence with the first and third fragments, removing the middle one (the zeros you must remove from your string). The references \1 and \2 refer to the first and the second parenthesized sub-expressions - the punctuation mark (colon or dash) and, respectively, the final digits (excluding the leading zeros that must be removed).

Format mask with leading zero for NUMBER

Which format mask should I use to convert number data from table column NUMBER to char if I want to preserve one leading zero and don't know data "size"? Value could have integral and/or fractional part. All that I know - it's NUMBER.
Source Data (numbers)
.12345678901234567890
100
100.500
12345678901234567890.1234567890
Desired result (text)
0.1234567890123456789
100
100.5
12345678901234567890.123456789
and so on, i.e. number could have unpredictable number of digits in whole part and unpredictable number of digits in fractional part.
A NUMBER data type is a binary value that has no format; if you want to format the number then you will need to convert it to another data-type that can represent the numeric value with a format, such as a VARCHAR2 data-type using the TO_CHAR function:
SELECT value,
RTRIM(
TO_CHAR( value, 'FM999999999999999999999990D99999999999999999999' ),
'.'
) AS formatted_number
FROM table_name
Which, for the sample data:
CREATE TABLE table_name ( value ) AS
SELECT .12345678901234567890 FROM DUAL UNION ALL
SELECT 100 FROM DUAL UNION ALL
SELECT 100.500 FROM DUAL UNION ALL
SELECT 12345678901234567890.1234567890 FROM DUAL
Outputs:
VALUE
FORMATTED_NUMBER
.1234567890123456789
0.1234567890123456789
100
100
100.5
100.5
12345678901234567890.123456789
12345678901234567890.123456789
number could have unpredictable number of digits in whole part and unpredictable number of digits in fractional part.
Just increase the number of 9s before and after the D decimal separator until the number of integer/fractional digits reaches your maximum precision.

FInd if the fifth position is a letter and not a number using ORACLE

How can I find if the fifth position is a letter and thus not a number using Oracle ?
My last try was using the following statement:
REGEXP_LIKE (table_column, '([abcdefghijklmnopqrstuvxyz])');
Perhaps you'd rather check whether 5th position contains a number (which means that it is not something else), i.e. do the opposite of what you're doing now.
Why? Because a "letter" isn't only ASCII; have a look at the 4th row in my example - it contains Croatian characters and these aren't between [a-z] (nor [A-Z]).
SQL> with test (col) as
2 (select 'abc_3def' from dual union all
3 select 'A435D887' from dual union all
4 select '!#$%&/()' from dual union all
5 select 'ASDĐŠŽĆČ' from dual
6 )
7 select col,
8 case when regexp_like(substr(col, 5, 1), '\d+') then 'number'
9 else 'not a number'
10 end result
11 from test;
COL RESULT
------------- ------------
abc_3def number
A435D887 not a number
!#$%&/() not a number
ASDĐŠŽĆČ not a number
SQL>
Anchor to the start of the string else you may get unexpected results. This works, but remove the caret (start of string anchor) and it returns 'TRUE'! Note it uses the case-insensitive flag of 'i'.
select 'TRUE'
from dual
where regexp_like('abcd4fg', '^.{4}[A-Z]', 'i');
Yet another way to do it:
regexp_like(table_column, '^....[[:alpha:]]')
Using the character class [[:alpha:]] will pick up all letters upper case, lower case, accented and etc. but will ignore numbers, punctuation and white space characters.
If what you care about is that the character is not a number, then use
not regexp_like(table_column, '^....[[:digit:]]')
or
not regexp_like(table_column, '^....\d')
Try:
REGEXP_LIKE (table_column, '^....[a-z]')
Or:
SUBSTR (table_column, 5, 1 ) BETWEEN 'a' AND 'z'

What does 'XXXXXX' mean as the second argument to TO_NUMBER? Oracle SQL

CREATE OR REPLACE TRIGGER fund_BIU
BEFORE INSERT OR UPDATE ON fund
FOR EACH ROW
BEGIN
IF INSERTING AND :new.fundid IS NULL THEN
:new.fundid := TO_NUMBER(SYS_GUID(), 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
END IF;
END;
/
I'm interested the IF statement. What does it mean
:new.fundid := to_number(sys_guid(),'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');. To be precise sys_guid(), 'xxxxxxxx' part.
TY
Think of the number 33. Focus on what that means - it's a number, it does not have digits. It can be represented as 3 * 10 + 3 * 1 which is why it has two digits in base 10, both digits equal to 3. But you could also represent it as 33.00. The strings '33' and '33.00' are clearly different (one has two characters, the other has five); but if you want to think of them as representing numbers, they represent the same number - the integer 33. Similarly, +33 and +33.00 represent the same number.
If you input a string like '33' or '+33.00' but you want to get out a number, then you use the function TO_NUMBER(). For example: '+33.00' is a string, but TO_NUMBER('+33.00') is a number, the number 33.
TO_NUMBER() allows you to give a format model, so that Oracle understands how to interpret the string it receives as input.
For example, if you input the string '1101' - is that the number one thousand one hundred one, or is it the number 13, given in binary representation?
Similarly, the number 33 has the string representation '21' in hexadecimal ("in HEX"). TO_NUMBER('21') will output the number 21; but you can tell Oracle that you meant a hexadecimal number, by providing the format model 'XX'. There are two X for two digits, and X is often used to mean "hex". So TO_NUMBER('21', 'XX') will output the number 33, not the number 21.
SYS_GUID() outputs the hexadecimal representation of a very large number. The output is a string. Applying TO_NUMBER() to it, with a format model that indicates it should be interpreted as a hex number, will convert it to an actual number (instead of a string of hex digits).
What SYS_GUID() does is generate a unique 16 byte identifier or key. When applying the TO_NUMBER() function, you are getting the 32 number representation of that key. It is basically a way of generating unique numbers in Oracle.
See SYS_GUID() in Oracle documentation: https://docs.oracle.com/cd/B12037_01/server.101/b10759/functions153.htm

Oracle cursor removes leading zero

I have a cursor which selects date from column with NUMBER type containg floating point numbers. Numbers like 4,3433 are returned properly while numbers smaller then 1 have removed leading zero.
For example number 0,4513 is returned as ,4513.
When I execute select used in the cursor on the database, numbers are formatted properly, with leading zeros.
This is how I loop over the recors returned by the cursor:
FOR c_data IN cursor_name(p_date) LOOP
...
END LOOP;
Any ideas why it works that way?
Thank you in advance.
You're confusing number format and number value.
The two strings 0.123 and .123, when read as a number, are mathematically equals. They represent the same number. In Oracle the true number representation is never displayed directly, we always convert a number to a character to display it, either implicitly or explicitly with a function.
You assume that a number between 0 and 1 should be represented with a leading 0, but this is not true by default, it depends on how you ask this number to be displayed. If you don't want unexpected outcome, you have to be explicit when displaying numbers/dates, for example:
to_char(your_number, '9990.99');
It's the default number formatting that Oracle provides.
If you want to specify something custom, you shall use TO_CHAR function (either in SQL query or PL/SQL code inside the loop).
Here is how it works:
SQL>
SQL> WITH aa AS (
2 select 1.3232 NUM from dual UNION ALL
3 select 1.3232 NUM from dual UNION ALL
4 select 332.323 NUM from dual UNION ALL
5 select 0.3232 NUM from dual
6 )
7 select NUM, to_char(NUM, 'FM999990D9999999') FORMATTED from aa
8 /
NUM FORMATTED
---------- ---------------
1.3232 1.3232
1.3232 1.3232
332.323 332.323
.3232 0.3232
SQL>
In this example, 'FM' - suppresses extra blanks, '0' indicates number digit including leading/trailing zeros, and '9' indicates digit suppressing leading/trailing zeros.
You can find many examples here:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34570

Resources