Using Quotation operator in sql in dynamic query - oracle

I am facing an issue,when I have to use quotation operator in function call.
For example:
Select replace( vstring, Cust_ref_Id, Vdata(vcount).cust_ref_id)
From dual;
Now my value of cust_ref_id holds Apostrophe.
Which I tried to handle using
Select replace( vstring, Cust_ref_Id, Vdata(vcount).q'[cust_ref_id]')
From dual;
But it's not working.
I have to tell Oracle that it needs to handle the apostrophe coming in the value you are receiving from Vdata(i).cust_ref_id.
How can I do that?

Related

How to evaluate an expression in one table field into another?

I have a table, inside there is a field called x, the x field contain value of '1+2', '1+3' etc, how to get these value and calculate it and save into another field?
For simple arithmetic expressions - and depending on your Oracle version - you could use xmlquery to evaluate. Note that / has special meaning in xml, the operator for division is the keyword div - so you need a replace in case you may have forward slashes in the arithmetic expression. (If you don't have any divisions, you can simplify the query by removing the call to replace.)
Here is an example - including the test data at the top, in a with clause (not part of the solution!)
with
test_data (str) as (
select '1 + 3' from dual union all
select '3 * 5 - 2' from dual union all
select '2/4*6' from dual union all
select '3 * (1 - 3)' from dual
)
select str, xmlquery(replace(str, '/', ' div ') returning content).getNumberVal()
as evaluated_expression
from test_data;
STR EVALUATED_EXPRESSION
----------- --------------------
1 + 3 4
3 * 5 - 2 13
2/4*6 3
3 * (1 - 3) -6
If you only have valid PL/SQL arithmetic expressions in your formulas, then you can use EXECUTE IMMEDIATE to evaluate them.
For this, you'll need to create a function:
create or replace function eval_expression(p_expression in varchar2)
return number is
query varchar2(100);
result number;
begin
query := 'select ' || p_expression || ' from dual';
execute immediate query
into result;
return result;
end eval_expression;
Then you can use this function in UPDATE query:
update t
--val is another field
set t.val = eval_expression(t.x)
Naturally, with EXECUTE IMMEDIATE this query won't be extremely efficient, but it'll work. Also, with dynamic queries we're going into unsafe territory, so make sure that you don't have malicious code among your formulas.
Also, see "Evaluate Expression" on Ask TOM. Tom Kyte used a slightly more civilized approach (dbms_sql package) and created a package with a single variable support.
If the case you have mentioned needs to be considered then I will suggest you use the following query:
select
xmlquery('3+4'
returning content
).getNumberVal()
from
dual;
If More operators are involved except division then the aforementioned query will work but if the division operator is also involved then you must have to replace "/" with " div " keyword. Something like the following:
select
xmlquery(
replace( '20/5', '/', ' div ')
returning content
).getNumberVal()
from
dual;
Now, you can use it in your update statement or anywhere else.
update tab
set tab.result_column_name = xmlquery(t.your_expr_column_name
returning content
).getNumberVal()
update tab
set tab.result_column_name = xmlquery(
replace( t.your_expr_column_name, '/', ' div ')
returning content
).getNumberVal()
Demo
Cheers!!

call function from sql script in oracle

In this code I am calling this FSG.REPLACE_STRING function which has 2 parameters, original string and special characters string. The original string is a select query from a table and special character string is 'A'.
I have written the code:
FSG.REPLACE_STRING ( (SELECT CAST(NVL(PRAD_ID , ' ') AS CHAR(12))
FROM FSG_WRK.FSG_PRCB_AUXDB_PRAD WHERE PRAD_ID= '003204091007'), A );
but this is not working.
You are trying to pass the table column value into the function, so you need to restructure your statement:
SELECT FSG.REPLACE_STRING (CAST(NVL(PRAD_ID, ' ') AS CHAR(12)), 'A')
FROM FSG_WRK.FSG_PRCB_AUXDB_PRAD
WHERE PRAD_ID= '003204091007';
Although the NVL() part seems a bit pointless if you're filtering for a specific (not-null) value in the query. Casting to char looks suspicious too.

Replace multiple substrings with one expression in Oracle SQL

I would like to delete multiple substrings from one column. I tried the replace function with the following code:
select replace('testetstestetststst', 'test'||'et'||'s', '')
from dual;
My expected result is ttt, but I get tstst.
In R it works with:
gsub("test|et|s", "", "testetstestetststst")
How can I replace many different substrings with nothing ('') in a column in clob format in Oracle SQL?
You need the REGEXP version of REPLACE:
select regexp_replace('testetstestetststst', 'test|et|s', '')
from dual;
In your code, you are concatenating strings, instead of using an OR operator; that is, your code is equivalent to
select replace('testetstestetststst', 'testets', '')
from dual;
Rather than using regular expressions, you can nest multiple REPLACE functions:
SELECT REPLACE(
REPLACE(
REPLACE(
'testetstestetststst',
'test'
),
'et'
),
's'
)
FROM DUAL;
We can directly use decode function.
select decode(job,'clerk','1','manager','2','salesman','3',4) from emp;
This will replace clerk with 1,manager with 2,salesman with 3 and other values with 4.

using sys_context to match data string

I'm trying to use data in sys_context form to perform a match in a WHERE clause.
What I put into the context is ('53','89'), which is what is returned when I select against dual.
My where statement is: where to_char(location_id) in sys_context('my_ctx','valoc')
Since I'm not getting the expected response, I'm guessing that what I think Oracle should see is not actually what it sees, but I don't know how to "look" at what's passed to the processor from TOAD.
The original form was where location_id in sys_context('my_ctx','valoc') with (53,89) in valoc, but that didn't return anything either. I'm sensing there may be no answer to my problem.
The problem is that the resulting WHERE clause is equivalent to this:
where to_char(location_id) in '('53','89')'
(didn't double the inner apostrophes for clarity)
The database sees what's retrieved from context as a single value, not as a list of values.
You can use the CONNECT BY trick to achieve your goal:
SELECT 1
FROM dual
WHERE '53' IN ( -- replace '53' with TO_CHAR(location_id)
SELECT regexp_substr('53,89', '[0-9]*', 1, level) -- replace '53,89' with sys_context('my_ctx','valoc')
FROM dual
CONNECT BY regexp_substr('53,89', '[0-9]*', 1, level) IS NOT NULL -- replace '53,89' with sys_context('my_ctx','valoc')
);

Select pkg_name.function_name

Is this query valid? if the package(with proper definition and body) and function exists and works fine.
Select "JK" As Name,
pckg_name1.function_name1(number1,number2)
from dual
The function call is fine (assuming the function returns a SQL data type - you cannot use PL/SQL specific data types, e.g. Boolean), but your quoting for JK is wrong. You have to use single quotes instead of double ones:
Select 'JK' As Name,
pckg_name1.function_name1(number1,number2)
from dual

Resources