PL/SQL: Exclamation Mark in ORACLE - oracle

What are those exclamation(!) marks in the following query?
l_sql := q'!
SELECT CASE WHEN FILTER_CNT = 0 THEN NULL ELSE FILTER_LIST END AS FILTER_LIST
FROM
(
SELECT 'TABLE_NAME NOT LIKE ' || LISTAGG(''''||EXCLUSION_CRITERIA||'''', ' AND TABLE_NAME NOT LIKE ') WITHIN GROUP (ORDER BY ROWNUM) AS FILTER_LIST, COUNT(*) AS FILTER_CNT
FROM !'|| p_after_owner ||q'!.UT_TABLE_EXCLUSION
WHERE EXCLUSION_TYPE = 'P'
)
!';

The q method of quoting strings means that you don't have to escape single quotes in the string.
As per the documentation, it works like this:
q'<single character delimiter><text><single character delimiter>'
Therefore, the !s in your sample string are acting as the quote delimiter.
For example, if you want to use the string Don't worry, be happy, in the old style quoting, that would become:
'Don''t worry, be happy'
but the new quoting mechanism would be:
q'!Don't worry, be happy!'
or
q'{Don't worry, be happy}'
etc.

Related

Oracle default escape character [duplicate]

If I want to select strings with underscores using Oracle SQL Developer, how do I have to escape those?
I tried:
name like '%_%'
name like '%'_%'
name like '%\_%'
but none of this helped.
You need to use the explicit escape; in this way you can decide a character to use for escaping and then use it in your LIKE.
For example, here I use the '!' to escape special characters:
select str
from (
select 'a_b' str from dual union all
select 'ab' from dual
)
where str like '%!_%' escape '!'
gives
STR
---
a_b
Oracle suggests the code below which workded for me:
SELECT last_name
FROM employees
WHERE last_name LIKE '%A\_B%' ESCAPE '\'
ORDER BY last_name;

Replacing multiple CHR() from PLSQL string

I have a PLSQL string which contains chr() special characters like chr(10), chr(13). I want to replace these special characters from the string. I tried the following ways
select regexp_replace('Hello chr(10)Goodchr(13)Morning','CHR(10)|chr(13)','') from dual;
This do not works since regexp_replace do not replace chr() function. Then I tried
select translate('Hello chr(10)Goodchr(13)Morning', 'chr(10)'||'chr(13)', ' ') from dual;
It works partially, ie; I am forced to replace chr() with white space(third parameter). No option if I do not want to replace chr() with white spaces . If I pass third character as null then above query returns null result.
Anybody have any other methods?
The problem with your replacement isn't the logic, it's the syntax. Parentheses are regex metacharacters, and as such, if you want to replace a literal parenthesis, you need to escape it. So your pattern should be this:
chr\(13\)|chr\(10\)
Here is a working query:
select
regexp_replace('Hello chr(10)Goodchr(13)Morning','chr\(13\)|chr\(10\)','', 1, 0, 'i')
from dual
The fifth parameters in the above call to regexp_replace is 'i' and indicates that we want to do a case insensitive replacement.
Demo
The above logic removes the literal text chr(13) and chr(10) from your text. If instead you want to remove the actual control characters chr(13) and chr(10), then you may add those control characters to the alternation, e.g.
select
regexp_replace('Hello chr(10)Goodchr(13)Morning','chr\(13\)|chr\(10\)|chr(10)|chr(13)','', 1, 0, 'i')
from dual
Since regular expression functions are relatively expensive in Oracle I think it's worth showing the alternate method which just uses REPLACE for the same effect.
This replaces occurrences of the each control characters with a space;
SELECT REPLACE(REPLACE('ABC'||CHR(10)||'DEF'||CHR(13)||'GHI'||CHR(10)||'JKL',CHR(13),' '),CHR(10),' ') from dual
And this replaces occurrences of the strings 'CHR(13)' and 'CHR(10)';
select REPLACE(REPLACE('ABCCHR(10)DEFCHR(13)GHICHR(10)JKL','CHR(13)',' '),'CHR(10)',' ') from dual

Cannot insert empty string in oracle table

i am trying to insert data into one of my table.
insert into t_transaction_query_log
(log_id,
posting_id,
fee_id,
fee_status,
fee_type,
pay_mode,
accounting_date,
policy_id,
money_id,
finish_time,
source_type,
fee_amount,
cr_seg,
dr_seg,
product_id' || v_insert_str_cr_seg ||
v_insert_str_dr_seg || ')
select s_transaction_query_log__lg_id.nextval,
tg.je_posting_id,
tg.fee_id,
tg.fee_status,
tg.fee_type,
60,
tg.accounting_date,
tg.policy_id,
tg.currency_id,
trunc(sysdate,
''dd''),
2,
tg.fee_amount,' ||v_str_cr_seg
|| ',' || v_str_dr_seg || ',
tg.product_id' || v_insert_str_cr_seg ||
v_insert_str_dr_seg || '
from t_ri_fee_gl tg
where tg.posted = ''Y''
i have declared v_str_cr_seg,v_str_dr_seg as empty strings i.e v_str_dr_seg varchar(50)='';
before executing this query i am able to append some values to these two strings
but in case there is no change in these strings from the declaration
i am getting the computed query as
insert into t_transaction_query_log
(log_id,
posting_id,
fee_id,
fee_status,
fee_type,
pay_mode,
accounting_date,
policy_id,
money_id,
finish_time,
source_type,
fee_amount,
cr_seg,
dr_seg,
product_id)
select s_transaction_query_log__lg_id.nextval,
tg.je_posting_id,
tg.fee_id,
tg.fee_status,
tg.fee_type,
60,
tg.accounting_date,
tg.policy_id,
tg.currency_id,
trunc(sysdate,
'dd'),
2,
tg.fee_amount, , ,
tg.product_id
from t_ri_fee_gl tg
where tg.posted = 'Y'
which in turn results in missing expression error.
i have tried using nvl function as
nvl(v_str_cr_seg, '') and `nvl(v_str_cr_seg, null)`
but still i am getting the same error
how can i insert even though v_str_cr_seg and v_str_dr_seg are unchanged
i.e empty strings ''
Ora DB:
empty string = null
enter link description here
Note:
Oracle Database currently treats a character value with a length of zero as null. However, this may not continue to be true in future releases, and Oracle recommends that you do not treat empty strings the same as nulls.
If this is an insert Statement in the middle of a PL/SQL Routine, then you would not string concatenate. It would rather look like this
tg.fee_amount, v_str_cr_seg, v_str_dr_seg
But something from your question tells me that you are composing a string that you want to execute immediate.
In this case you have to make sure you are giving quotes:
tg.fee_amount,''' ||v_str_cr_seg
|| ''',''' || v_str_dr_seg || ''',
tg.product_id''' || v_insert_str_cr_seg ||
v_insert_str_dr_seg || '''
You need to escape the single quote (') with two quotes in a row ('')
But if your strings already come with quotes around it unless null you may want to work with nvl this way
tg.fee_amount,' ||nvl(v_str_cr_seg,'''''')
|| ',' || nvl(v_str_dr_seg,'''''') || ',
Try using chr(0) instead of ''. Null character is a sign of the end of a string.

Oracle substring select questions

Got stuck
select *
from table a
where ID like 'delr' || trim(substr(busns_asct_id,5)) || '%';
based on the above query, I get records like "delr112591-8218-1" but in that I need to eliminate ID like "delr60201-T,delr99999-A" and "delr1 -5"
How to eliminate this?
This how to deal with LIKE in Oracle:
An underscore _ in the pattern matches exactly one character
A percent sign % in the pattern can match zero or more characters
ESCAPE '\' to escape the _ or % with any character you want, here I used \
To match delr112591-8218-1 you can use that
like 'delr' || trim(substr(busns_asct_id,5)) || '-____-_';
any other string obtained by replacing _ by any other character will match, so "delr60201-T","delr99999-A" and "delr1 -5" will not match, if you want something more accurate, you have to use REGEX.
LIKE condition in Oracle
REGEX in Oracle
select *
from table a
where ID like 'delr' || trim(substr(busns_asct_id,5)) || '-_' or ID like 'delr_-_;

Oracle Regexp to replace \n,\r and \t with space

I am trying to select a column from a table that contains newline (NL) characters (and possibly others \n, \r, \t). I would like to use the REGEXP to select the data and replace (only these three) characters with a space, " ".
No need for regex. This can be done easily with the ASCII codes and boring old TRANSLATE()
select translate(your_column, chr(10)||chr(11)||chr(13), ' ')
from your_table;
This replaces newline, tab and carriage return with space.
TRANSLATE() is much more efficient than its regex equivalent. However, if your heart is set on that approach, you should know that we can reference ASCII codes in regex. So this statement is the regex version of the above.
select regexp_replace(your_column, '([\x0A|\x0B|`\x0D])', ' ')
from your_table;
The tweak is to reference the ASCII code in hexadecimal rather than base 10.
select translate(your_column, chr(10)||chr(11)||chr(13), ' ') from your_table;
to clean it is essential to serve non-null value as params ...
(oracle function basically will return null once 1 param is null, there are few excpetions like replace-functions)
select translate(your_column, ' '||chr(10)||chr(11)||chr(13), ' ') from your_table;
this examples uses ' '->' ' translation as dummy-value to prevent Null-Value in parameter 3

Resources