REGEXP_REPLACE expression issue - sql

I got some sql script below to remove word between words, but it will find last occurrence of my (/hide) instead of the first occurrence. Need help to get the output as expected. Thanks.
select regexp_replace('(hide)it(/hide)should be show(hide)my(/hide) text',
'^\(hide\).*\(/hide\)', '') "TESTING"
from dual;
I expect the output will be:
should be show text
but the actual output is:
text
If my data is in one of the column with datatype of clob. As currently i use below script to select. For example my table is testing_table with column of desc_str with data_type of clob which inside contain value '(hide)it(/hide)should be show(hide)my(/hide) text';
select trim(to_char(regexp_replace(desc_str,'^\(hide\).*\(/hide\)',''))) as desc
from testing_table
where OOE_FP_SS_ID = $id;

Based on your example:
SQL> with test (col) as
2 (select '(hide)it(/hide)should be show(hide)my(/hide) text' from dual)
3 select regexp_replace(col, '\(hide\)\w+\(/hide\)', '') result
4 from test;
RESULT
-------------------
should be show text
SQL>
[EDIT: CLOB]
You asked for a CLOB. Here's an example:
SQL> create table test (desc_str clob);
Table created.
SQL> insert into test values ('(hide)it(/hide)should be show(hide)my(/hide) text');
1 row created.
SQL> select regexp_replace(desc_str, '\(hide\)\w+\(/hide\)', '') result from test;
RESULT
--------------------------------------------------------------------------------
should be show text
SQL>
Another example:
SQL> with test (desc_str) as
2 (select '(hide)ItemId: 4334(/hide)|(hide)Description Item - SubType:(/hide) Name - Item|(irow)Price Value: MYR 1,668' from dual)
3 select regexp_replace(desc_str, '\(hide\).+?\(/hide\)', '') result from test;
^
RESULT | this question mark was missing
------------------------------------------
| Name - Item|(irow)Price Value: MYR 1,668
SQL>

Related

How to pass string data type to number datatype in plsql

I have procedure like this...
declare
v_psg varchar2(10);
id_no number;
begin
select value into v_psg from settings_am where key = 'PSG';
select id into id_no from product where to_char(psg) in (v_psg);
end;`
The value returned from select value into v_psg from settings_am where key = 'PSG'; would be
'1','2','3'
when i run this procedure i am returned with ora error - ORA-01403.
please advise how i should pass the v_psg value to psg column of product table?
EDIT - Tried with test case suggested
If you got ORA-01403, you were kind of lucky. It is the NO_DATA_FOUND error, which means that one (probably the first) query didn't return anything.
Those two statements could be combined into
select id
from product
where to_char(psg) in (select value
from settings_am
where key = 'PSG'
);
Why would you select value first, and then use it in another query? Besides, it just wouldn't work. v_psg is declared as VARCHAR2 variable. The way you described it, it contains the following string: '1','2','3', as if this is what you have:
SQL> create table settings_am (key varchar2(10),
2 value varchar2(20)); --> note size here
Table created.
SQL> insert into settings_am (key, value)
2 values ('PSG', q'['1','2','3']');
1 row created.
SQL> select * From settings_am;
KEY VALUE
---------- --------------------
PSG '1','2','3'
SQL>
As you can see, I enlarged the value column size, although variable you declared says 10. Why? Because of
SQL> select length(value) from settings_am where key = 'PSG';
LENGTH(VALUE)
-------------
11
i.e. you can't put something that is long 11 into something that accepts length 10.
Or, if your data actually contains 3 rows for the PSG key, are those values already enclosed into single quotes? If so, that's strange; people usually don't do that. Anyway, suppose that you managed to get string '1,2,3' (which is what I presume you actually have) into a VARCHAR2 variable, then you have to split it into rows in order to be able to use it in the IN clause:
SQL> create table product (id number, psg varchar2(10));
Table created.
SQL> insert into product (id, psg) values (100, '1');
1 row created.
SQL> insert into product (id, psg) values (200, '2');
1 row created.
SQL>
Query is then (where lines #3 - 5 represent splitting a string into rows):
SQL> select p.id
2 from product p
3 where p.psg in (select regexp_substr('&&v_psg', '[^,]+', 1, level)
4 from dual
5 connect by level <= regexp_count('&&v_psg', ',') + 1
6 );
Enter value for v_psg: 1,2,3
ID
----------
100
200
So, wouldn't it be simpler to use
SQL> select id
2 from product
3 where to_char(psg) in (select value
4 from settings_am
5 where key = 'PSG'
6 );
ID
----------
100
200
SQL>
Note that both options also show why your query is wrong: you can't put two values (rows) into a variable declared as id_no number; as you'd get TOO_MANY_ROWS error.
Finally, what is it that you'd want to do? What problem are you trying to solve? Apparently, except for special cases (only one row for each value) your query can't work. If you could provide test case (create table & insert into sample data), as well as expected output, it would be easier to help you.

Decimal point is removed before update to character variable

I have data in the below format and I want to update a destination table column of type varchar2 with below values. But the problem is it updates as .462 instead of 0.462 by using trim with leading '0'.
source destination column
----------------- ------------------
0000004.304300000 4.3043
0000005.504500000 5.5045
0000141.400000000 141.4
0000138.900000000 138.9
0000000.462000000 0.462
0000000.000297000 0.000297
A little bit of TO_CHARing and TO_NUMBERing with appropriate format mask might do the job. Have a look at the example:
SQL> create table test (source varchar2 (20), destination varchar2(20));
Table created.
SQL> insert into test (source)
2 select '0000004.304300000' from dual union all
3 select '0000000.462000000' from dual union all
4 select '0000141.400000000' from dual union all
5 select '0000033.000000000' from dual;
4 rows created.
SQL> alter session set nls_numeric_characters = '.,';
Session altered.
SQL> update test set
2 destination = rtrim(to_char(to_number(source), 'fm999990D99999999'), '.');
4 rows updated.
SQL> select * From test;
SOURCE DESTINATION
-------------------- --------------------
0000004.304300000 4.3043
0000000.462000000 0.462
0000141.400000000 141.4
0000033.000000000 33
SQL>

Use special character '%' to append the string in update statement

I need to update a table where the table column is of varchar2 datatype and need to update the value of columns with '%'.
for example --
create table test (id number, name varchar2(20));
insert into test values (1, 'smith');
insert into test values (2, 'allen');
Now we need to update the values in NAME column to smith'%'
So it should also include the single quotes in the string.
I am able to update it to smith% but it should be smith'%'
update test
set name = 'smith'||'''%'''
where id = 1;
SQL Error: ORA-00911: invalid character
Your query works perfectly in SQLPlus:
SQL> update test
2 set name = 'smith'||'''%'''
3 where id = 1;
1 row updated.
SQL> select * from test;
ID NAME
---------- --------------------
1 smith'%'
2 allen
This could be another way, avoiding the need to double the quotes:
SQL> update test
2 set name = 'allen'|| q'['%']'
3 where id = 2;
1 row updated.
SQL> select * from test;
ID NAME
---------- --------------------
1 smith'%'
2 allen'%'
Or even, avoiding the ||:
SQL> update test
2 set name = concat(name, q'['%']')
3 where id = 1;
1 row updated.
SQL> select * from test;
ID NAME
---------- --------------------
1 smith'%''%'
2 allen'%'
SQL> set define off;
verify this link
how-to-enter-special-characters-like-in-oracle-database
Actually your statement should work, I just tested it in my database.
update test
set name = concat('smith', '''%''')
where id = 1;

Oracle:Set default value for number column

How can we set default value for a number typed column has '00'?I tried this but it still saved it has '0',I need to do this.
//alter table table_name add column column1 default '00';
Please suggest a way for me.
You can store as number and when you retrieve do as
select column1,to_char(column2,'00') from mytable
SQL Fiddle Demo
It is not possible to store numbers like that - In a format you have described ('00'). You can store numbers as numbers (as values of numeric data type of course) and use to_char function or to_char function combined with lpad function to represent numbers in a format you like. Here is an example:
SQL> create table TB_SingleNumberColumn(
2 col number
3 )
4 /
Table created
SQL> insert into TB_SingleNumberColumn(Col) values(1);
1 row inserted
SQL> insert into TB_SingleNumberColumn(Col) values(5);
1 row inserted
SQL> insert into TB_SingleNumberColumn(Col) values(11);
1 row inserted
SQL> insert into TB_SingleNumberColumn(Col) values(111);
1 row inserted
SQL> commit;
Commit complete
-- The values as they are
SQL> select * from TB_SingleNumberColumn;
COL
----------
1
5
11
111
-- Values padded with zeros.
SQL> select to_char(col, '000') res
2 from TB_SingleNumberColumn;
RES
----
001
005
011
111
SQL> select lpad(to_char(col), 3, '0')
2 from TB_SingleNumberColumn
3 ;
LPAD(TO_CHAR(COL),3,'0')
------------------------
001
005
011
111

Is it possible to update data inside a CLOB using SQL?

I have a table having one clob column which has XML data in it.
Say I want to replace XYZ with ABC in the clob column.
Is it possible using sqlplus?
Why not try it ?
SQL> create table nnn(c1 clob);
Table created.
SQL> insert into nnn values ('text ABC end');
1 row created.
SQL> select * from nnn;
C1
-------------------------------------------------
text ABC end
SQL> update nnn set c1=replace(c1,'ABC','XYZ');
1 row updated.
SQL> select * from nnn;
C1
-------------------------------------------------
text XYZ end
SQL>
"i have new line in the column. any
advice?"
Newlines are characters; if you want to amend text which contains them you need to include them in the search string. You can do this using the CHR() which takes an ASCII value as an argument. The precise codes you need to include vary according to OS. Because I ran this example on MS Windows I needed to pass both linefeed (ASCII=10) and carriage return (ASCII=13).
SQL> select * from t42
2 /
TXT
--------------------------------------------------------------------------------
<ABC> ABCD
</ABC>
SQL> update t42 set txt=replace(txt,'ABCD'||chr(10)||chr(13), 'APC woz here')
2 /
1 row updated.
SQL> select * from t42
2 /
TXT
--------------------------------------------------------------------------------
<ABC> APC woz here </ABC>
SQL>
Incidentally, if you are storing XML text it might be worthwhile using the XMLType datatype for the column instead of CLOB. It comes with a lot of useful functionality.
Yes, it's possible with one REPLACE() function. Try:
update nnn set c1 = REPLACE(c1,'ABC>','XYZ>')