APEX validate alphabetic only allowed - oracle

In APEX 5.1 looking for validation script help to only allow alphabetic characters and a space or hyphen for a person's name. (i.e. no numbers or special characters other than a possible dash allowed).
I have a working validation for another field which allows alphanumeric but not special characters! Validation type is "Item does NOT contain any of the characters in Value". In the value field the following is placed... !##$%^&*()-_+=[]{};:'",<.>/?\|

I'd suggest you to use validation whose type is a function that returns Boolean and looks like this:
return regexp_like(:P1_ITEM_NAME, '^[A-Za-z -]+$');
What does it do?
^ is anchor to the beginning of the string
A-Z accepts capital letters
a-z accepts lowercase letters
space is ... well, a space
- is ... well, a hyphen
+ - repeat those characters many times
$ is anchor to the end of the string
For example:
SQL> with test (item) as
2 (select 'aBCd' from dual union -- ok
3 select 'little foot' from dual union -- ok
4 select 'reb-ecca' from dual union -- ok
5 select 'lit123foot' from dual union -- wrong
6 select 'abc$3' from dual union -- wrong
7 select 'xy.)z' from dual union -- wrong
8 select '123-234' from dual -- wrong
9 )
10 select item
11 from test
12 where regexp_like(item, '^[A-Za-z -]+$');
ITEM
-----------
aBCd
little foot
reb-ecca
SQL>

Related

Allow multiple values from SSRS in oracle

I have a query that gets contract_types 1 to 10. This query is being used in an SSRS report to filter out a larger dataset. I am using -1 for nulls and -2 for all.
I would like to know how we would allow multiple values - does oracle concatenate the inputs together so '1,2,3' would be passed in? Say we get select -1,0,1 in SSRS, how could we alter the bottom query to return values?
My query to get ContractTypes:
SELECT
ContractType,
CASE WHEN ContractType = -2 THEN 'All'
WHEN ContractType = -1 THEN'Null'
ELSE to_Char(ContractType)
END AS DisplayFigure
FROM ContractTypes
which returns
ContractType DisplayFig
-1 Null
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
This currently is only returning single values or all, not muliple values:
SELECT *
FROM Employee
WHERE NVL(CONTRACT_TYPE, -1) = :contract_type or :contract_type = -2
I'm assuming we want to do something like:
WHERE NVL(CONTRACT_TYPE, -1) IN (:contract_type)
But this doesn't seem to work.
Data in Employee
Name ContractType
Bob 1
Sue 0
Bill Null
Joe 2
In my report, I want to be able to select contract_type as -1(null),0,1 using the 'allow muliple values' checkbox. At the moment, I can only select either 'all' using my -2 value, or single contract types.
My input would be: contract type = -1,1,2
My output would be Bill, Bob, Joe.
This is how I'm executing my code
I use SSRS with Oracle a lot so I see where you're coming from. Thankfully, they work pretty well together.
First make sure the parameter is set to allow multiple values. This adds a Select All option to your dropdown so you don't have to worry about adding a special case for "All". You'll want to make sure the dataset for the parameter has a row with -1 as the Value and a friendly description for the Label.
Next, the WHERE clause would be just as you mentioned:
WHERE NVL(CONTRACT_TYPE, -1) IN (:contract_type)
SSRS automatically populates the values. There is no XML or string manipulation needed. Keep in mind that this will not work with single-value parameters.
If for some reason this still doesn't work as expected in your environment, there is another workaround you can use which is more universal and works even with ODBC connections.
In the dataset parameter properties, use an expression like this to concatenate the values into a single, comma-separated string:
="," + Join(Parameters!Parameter.Value, ",") + ","
Then use an expression like this in your WHERE clause:
where :parameter like '%,' + Column + ',%'
Obviously, this is less efficient because it most likely won't be using an index, but it works.
I don't know SSRS, but - if I understood you correctly, you'll have to split that comma-separated values list into rows. Something like in this example:
SQL> select *
2 from dept
3 where deptno in (select regexp_substr('&&contract_type', '[^,]+', 1, level)
4 from dual
5 connect by level <= regexp_count('&&contract_type', ',') + 1
6 );
Enter value for contract_type: 10,20,40
DEPTNO DNAME LOC
---------- -------------------- --------------------
20 RESEARCH DALLAS
10 ACCOUNTING NEW YORK
40 OPERATIONS BOSTON
SQL>
Applied to your code:
select *
from employee
where nvl(contract_type, -1) in (select regexp_substr(:contract_type, '[^,]+', 1, level)
from dual
connect by level <= regexp_substr(:contract_type, ',') + 1
)
If you have the comma separated list of numbers and then if you like to split it then, the below seems simple and easy to maintain.
select to_number(column_value) from xmltable(:val);
Inputs: 1,2,3,4
Output:
I guess I understood your problem. If I am correct the below should solve your problem:
with inputs(Name, ContractType) as
(
select 'Bob', 1 from dual union all
select 'Sue', 0 from dual union all
select 'Bill', Null from dual union all
select 'Joe', 2 from dual
)
select *
from inputs
where decode(:ContractType,'-2',-2,nvl(ContractType,-1)) in (select to_number(column_value) from xmltable(:ContractType))
Inputs: -1,1,2
Output:
Inputs: -2
Output:

oracle forms 12. how to display leading zero of decimal numbers

I wish to display decimal numbers (from a query) into text items.
if I set
:TXT_ITEM := '0,000123456789'
it works. But, if :TXT_ITEM is bound to a numeric table field, value is displayed as ,000123456789.
I'm trying to force format number on several triggers (post-change, when-new-record-instance, post-text...), unsuccessfully. On other hand, setting format_mask would force my DB value to a given number of decimal digits.
How can I get leading zero to be displayed?
See if any of these two options help.
Sample data:
SQL> create table test as
2 (select 12.34 col from dual union all
3 select 0.1234003 from dual union all
4 select -13.43432203 from dual union all
5 select 0.00012345221 from dual union all
6 select -0.002412428238234821 from dual
7 );
Table created.
SQL> desc test;
Name Null? Type
----------------------------------------- -------- ----------------------------
COL NUMBER
SQL> select col,
2 regexp_replace(col, '^(-?)([.,])', '\10\2') result1,
3 rtrim(to_char(col, 'fm90D999999999999999999999'), '.') result2
4 from test;
COL RESULT1 RESULT2
---------- ------------------------- -------------------------
12,34 12,34 12,34
,1234003 0,1234003 0,1234003
-13,434322 -13,43432203 -13,43432203
,000123452 0,00012345221 0,00012345221
-,00241243 -0,002412428238234821 -0,002412428238234821
SQL>
How would use it/them in Forms? Exactly like that - you'd e.g.
select regexp_replace(col, '^(-?)([.,])', '\10\2')
into :block.text_item
from your_table
where some_condition;
Seems the concerned numeric data in the table is of type
NUMBER(13,12)
in this case it's enough to set TXT_ITEMs Format Mask attribute within the Data part of Property Palette as
0D000000000000
with precision of 13 and scale of 12 values.
Considering the scale part is fixed, you can add more zeroes before D character depending on your column's precision value such as two zeroes before D are kept for NUMBER(14,12) or three zeroes for NUMBER(15,12).

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'

Oracle change any string to a number

I'm having this problem we have this database witch IDS are stored in varchar2 type this ids contains Letters.
Is there any solution to convert a string to a number no matter what the value if this string.
for example there is : SELCT ASCII('t') FROM DUAL; result : 116.
but ASCII accept only one CHAR Hope you get the idea. sorry for my english
use oracle translate method to replace A-Z or a-z characters with numbers.
then use to_number to get number from it.
select translate('A1B2C3', 'ABC', '456') from dual; --result '415263'
select to_number(translate('A1B2C3', 'ABC', '456')) from dual; --result 415263
translate function documentation
The Oracle/PLSQL TRANSLATE function replaces a sequence of characters in a string with another set of characters. However, it replaces a single character at a time.
For example, it will replace the 1st character in the string_to_replace with the 1st character in the replacement_string. Then it will replace the 2nd character in the string_to_replace with the 2nd character in the replacement_string, and so on.
EDIT: After discussing further with the OP, it turns out he needed a function (in the mathematical sense) from short strings to integers. Such a function is ORA_HASH. The OP decided that ORA_HASH is likely what is needed for his project.
https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions112.htm#SQLRF06313
The solution below is kept for historical perspective.
You could use the analytic function DENSE_RANK to assign numbers to strings.
For example:
with
employees ( id, first_name, last_name ) as (
select 'ABC', 'Jane', 'Smith' from dual union all
select 'ABD', 'Jane', 'Dryer' from dual union all
select 'XYZ', 'Mike', 'Lopez' from dual
)
-- End of simulated inputs (for testing purposes only).
-- Solution (SQL query) begins below this line.
select id, dense_rank() over (order by id) as num_id, first_name, last_name
from employees
;
ID NUM_ID FIRST_NAME LAST_NAME
--- ------ ---------- ---------
ABC 1 Jane Smith
ABD 2 Jane Dryer
XYZ 3 Mike Lopez

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