Evaluate Expression from PL/SQL without passing it SQL engine
I have an expression similar to '1+2+(3*6)/12*ROUND(10*3, 3)' which I generate programatically in VARCHAR2 variable. One way to calculate the expression is execute immediate 'select '||exp||' from dual' into lv_x; which would return the value. But my shared pool is filling up as I do this thousands of times may more in some cases. I unsuccessfully tried to use bind variables.
1. Is there a way to temporarily turn shared pool off before the query an enable it after executing the query?
2. Is there a simple function in PL/SQL which evaluvates the expression? If not I may have to painfully write one.
Please advice
few additional coffee breaks to put together a functions version (not heavily tested)
create or replace function evaluate_expression(p_expression in varchar2) return number is
ret_val number;
sep varchar2(1) := '|';
operand_stack varchar2(4000) := sep;
operator_stack varchar2(4000) := sep;
function_stack varchar2(4000) := sep;
w_expression varchar2(4000) := replace(p_expression,' ','');
i pls_integer := 1;
next_char varchar2(1);
num_in boolean := false;
opr_in boolean := false;
fun_in boolean := false;
top_function varchar2(100);
top_operator varchar2(100);
left_operand varchar2(100);
right_operand varchar2(100);
function pop_stack(p_stack in out varchar2) return varchar2 is
ret_val varchar2(4000);
begin
ret_val := rtrim(substr(p_stack,instr(p_stack,sep,-1,2) + 1),sep);
p_stack := substr(p_stack,1,instr(p_stack,ret_val||sep,-1,1) - 1);
dbms_output.put_line('pop stack: '''||ret_val||''' = '||substr(p_stack,1,100));
return ret_val;
end;
function peek_stack(p_stack in varchar2) return varchar2 is
ret_val varchar2(4000);
begin
ret_val := substr(rtrim(p_stack,sep),instr(rtrim(p_stack,sep),sep,-1) + 1);
dbms_output.put_line('peek stack = '''||ret_val||''' '||substr(p_stack,1,100));
return ret_val;
end;
procedure push_stack(p_stack in out varchar2,p_item in varchar2) is
begin
p_stack := replace(p_stack || p_item || sep,sep || sep,sep);
dbms_output.put_line('push stack: '''||p_item||''' = '||substr(p_stack,1,100));
end;
function is_empty(p_stack in varchar2) return boolean is
ret_val boolean;
begin
if p_stack = sep then
ret_val := true;
else
ret_val := false;
end if;
return ret_val;
end;
function precedence(p_operator in varchar2) return pls_integer is
ret_val pls_integer;
begin
if p_operator in ('+','-') then
ret_val := 1;
elsif p_operator in ('*','/') then
ret_val := 2;
elsif p_operator in ('^') then
ret_val := 3;
elsif p_operator in ('(') then
ret_val := 0;
elsif p_operator in (')') then
ret_val := 0;
elsif p_operator in ('F') then
ret_val := -1;
else
ret_val := 4;
end if;
return ret_val;
end;
function evaluate_operation(p_left in varchar2,p_right in varchar2,p_operator in varchar2) return number is
ret_val number := to_number(null);
begin
if p_operator = '+' then
ret_val := to_number(p_left) + to_number(p_right);
elsif p_operator = '-' then
ret_val := to_number(p_left) - to_number(p_right);
elsif p_operator = '*' then
ret_val := to_number(p_left) * to_number(p_right);
elsif p_operator = '/' then
ret_val := to_number(p_left) / to_number(p_right);
elsif p_operator = '^' then
ret_val := power(to_number(p_left),to_number(p_right));
end if;
dbms_output.put_line('evaluate operation: ('||p_left||')'||p_operator||'('||p_right||') = '||to_char(ret_val));
return ret_val;
end;
function evaluate_function(p_function in varchar2) return number is
ret_val number := to_number(null);
begin
if p_function = 'ROUND' then
right_operand := pop_stack(operand_stack);
left_operand := pop_stack(operand_stack);
ret_val := round(to_number(left_operand),to_number(right_operand));
dbms_output.put_line('evaluate function: round['||left_operand||';'||right_operand||']');
elsif p_function = 'TRUNC' then
right_operand := pop_stack(operand_stack);
left_operand := pop_stack(operand_stack);
ret_val := trunc(to_number(left_operand),to_number(right_operand));
dbms_output.put_line('evaluate function: trunc['||left_operand||';'||right_operand||']');
end if;
return ret_val;
end;
procedure treat_operand(p_char in varchar2) is
begin
operand_stack := operand_stack || p_char;
end;
procedure treat_operator(p_char in varchar2) is
done boolean := false;
result number;
begin
if num_in then
push_stack(operand_stack,'');
num_in := false;
end if;
while not done loop
if is_empty(operator_stack) or p_char = '(' then
push_stack(operator_stack,p_char);
done := true;
else
top_operator := peek_stack(operator_stack);
if precedence(p_char) > precedence(top_operator) then
push_stack(operator_stack,p_char);
done := true;
else
top_operator := pop_stack(operator_stack);
if top_operator = '(' then
done := true;
else
right_operand := pop_stack(operand_stack);
left_operand := pop_stack(operand_stack);
result := evaluate_operation(left_operand,right_operand,top_operator);
push_stack(operand_stack,to_char(result));
end if;
end if;
end if;
end loop;
end;
procedure treat_function(p_char in varchar2) is
result number;
begin
if p_char = '[' then -- function parameters in square brackets
push_stack(function_stack,'');
push_stack(operator_stack,'F');
elsif p_char = ';' then -- ';' function parameter separator (my decimal point is comma)
push_stack(operand_stack,'');
while peek_stack(operator_stack) != 'F' loop
top_operator := pop_stack(operator_stack);
right_operand := pop_stack(operand_stack);
left_operand := pop_stack(operand_stack);
ret_val := evaluate_operation(left_operand,right_operand,top_operator);
push_stack(operand_stack,to_char(ret_val));
end loop;
elsif p_char = ']' then -- function parameters in square brackets
push_stack(operand_stack,'');
while peek_stack(operator_stack) != 'F' loop
top_operator := pop_stack(operator_stack);
right_operand := pop_stack(operand_stack);
left_operand := pop_stack(operand_stack);
ret_val := evaluate_operation(left_operand,right_operand,top_operator);
push_stack(operand_stack,to_char(ret_val));
end loop;
top_operator := pop_stack(operator_stack);
top_function := pop_stack(function_stack);
ret_val := evaluate_function(upper(top_function));
push_stack(operand_stack,to_char(ret_val));
while peek_stack(operator_stack) not in ('F','(') loop
top_operator := pop_stack(operator_stack);
right_operand := pop_stack(operand_stack);
left_operand := pop_stack(operand_stack);
ret_val := evaluate_operation(left_operand,right_operand,top_operator);
push_stack(operand_stack,to_char(ret_val));
end loop;
else
function_stack := function_stack || p_char;
end if;
end;
begin
if substr(w_expression,1,1) = '-' then
w_expression := '0' || w_expression;
elsif substr(w_expression,1,1) = '+' then
w_expression := substr(w_expression,2);
end if;
w_expression := replace(replace(replace(w_expression,'(-','(0-'),'(+','('),'[-','[0-');
while true loop
next_char := substr(w_expression,i,1);
dbms_output.put_line('loop next_char('||to_char(i)||') = '''||next_char||'''');
exit when next_char is null;
if next_char in ('0','1','2','3','4','5','6','7','8','9',',') then -- ',' = decimal point
treat_operand(next_char);
num_in := true;
elsif next_char in ('+','-','*','/','^','(',')') then
treat_operator(next_char);
if not fun_in then
opr_in := true;
end if;
else
treat_function(next_char);
fun_in := true;
end if;
i := i + 1;
end loop;
push_stack(operand_stack,'');
while not is_empty(operator_stack) loop
top_operator := pop_stack(operator_stack);
if top_operator = 'F' then
top_function := pop_stack(function_stack);
ret_val := evaluate_function(upper(top_function));
else
if top_operator != '(' then
right_operand := pop_stack(operand_stack);
left_operand := pop_stack(operand_stack);
ret_val := evaluate_operation(left_operand,right_operand,top_operator);
end if;
end if;
push_stack(operand_stack,to_char(ret_val));
end loop;
left_operand := pop_stack(operand_stack);
ret_val := to_number(left_operand);
dbms_output.put_line('operand_stack = '||substr(operand_stack,1,100));
dbms_output.put_line('operator_stack = '||substr(operator_stack,1,100));
dbms_output.put_line('function_stack = '||substr(function_stack,1,100));
dbms_output.put_line(w_expression||' = '||to_char(ret_val));
if is_empty(operand_stack) and is_empty(operator_stack) and is_empty(function_stack) then
return ret_val;
else
return to_number(null);
end if;
end;Regards
Etbin
some comments added
to keep it simple:
- stacks are just strings (elements separated by pipes) on developing everything is revealed at first glance
- function parameters are specified in square brackets separated by semicolons (comma is our decimal point)
- dbms_output.put_line intentionally kept in place as on developing provided sufficient trace info
Edited by: Etbin on 9.6.2009 21:07
Similar Messages
-
How to get month value from custom calendar without passing parameter from SSRS in MDX query
Could you please throw some light to achieve below requirement?
I need to filter the data between two periods dynamically . The date calendar here works differently(ex:-Date 26-Aug-2014 will fall in period 7 which is last date and 27-Aug-2014 will fall in period 8 and it is first date of period 8),so I cannot go
with system date period/Month. Date Hierarchy is like YEAR,QUARTER,PERIOD ,WEEK and DAY.
I cannot use SSRS for passing parameter. Requirement is to extract last 2 period of data dynamically in Power Pivot with MDX.
Thanks ChandanHi Chandan,
You might try something like this
Tail(null:
Extract(
StrToMember("[FYDay].[DATE].&[ + cStr(Format(Now(),"yyyy-MM-ddT00:00:00")) + "]")
*[FYDay].[DateHierarchy].[Day]
,[FYDay].[DateHierarchy]).parent.parent
,2)
What it is doing is multiplying Day by the current date, which returns a set of one date with cardinality of (Date,Day). The Extract is pulling out just the datehierarchy Day. the the Tail() is getting it and the previous day.
Hope that helps,
Richard -
PL/SQL array passed to SQL IN
Hi,
I have a PL/SQL array which type is defined like this:
create or replace type type_id_array as table of number(6, 3);
then i create a variable and initilaize:
var_1 type_id_array;
var_1 := .....
then i have a select statement.
select * from table t where t.id in(var_1)
That's it, i want to use the array in an SQL in. This seems not possible.
Can you explain why? Any alternate solutions?
Thanksuser610868 wrote:
That's it, i want to use the array in an SQL in. This seems not possible.
Can you explain why? Any alternate solutions?SQL supports set commands specifically for arrays (in addition to the using the TABLE() method mentioned). For example:
SQL> create or replace type TNumbers is table of number;
2 /
Type created.
SQL>
SQL> declare
2 numList TNumbers;
3 cnt integer;
4 begin
5 numList := new TNumbers(1,2,3,4,5,6,7);
6 select
7 count(*) into cnt
8 from user_objects
9 where TNumbers(object_id) member of numList;
10 DBMS_OUTPUT.put_line( 'cnt='||cnt );
11 end;
12 /
cnt=0
PL/SQL procedure successfully completed.Obviously there are performance considerations when using arrays/collections in SQL. So before choosing a method, evaluate the performance. -
See sql query from crystal report without crystal report
see sql query from crystal report without crystal report
Hi,
Depends on datasource type but you could have a look at ODBC trace or if you have access to the SQL Server you could use profiler to monitor the session.
Regards,
Craig
And this will only be of use if you know which Server/Insstance/Database the Report is connecting to...
Please click "Mark As Answer" if my post helped. Tony C. -
Is it possible to transfer a database from SQL Server 2012 to SQL Server Express 2012?
Is it possible to transfer a database from SQL Server 2012 to
SQL Server Express 2012? Ideally I would like to backup the database from SQL Server 2012 and restore it on SQL Server Express 2012. Is that possible?Is it possible to transfer a database from SQL Server 2012 to
SQL Server Express 2012? Ideally I would like to backup the database from SQL Server 2012 and restore it on SQL Server Express 2012. Is that possible?
Yes it is possible but database size should not be greater than 10 G as max databse size supported for Express 2012 is 10 G
Please mark this reply as the answer or vote as helpful, as appropriate, to make it useful for other readers -
How to make data base link from oracle 11g r2 to microsoft sql 2008 express
I need to make data base link from oracle 11g r2 to microsoft sql 2008 express to make replication between then
please help me !
I didn't know what is the user and password in the command which create database linkTo replicate data you can ude Database Gateway for ODBC or Database Gatewy for MS SQl Server. Please use the search engine of this forum if you ant to get more details about each product.
Some SQl Servers are set up to use Windows authentication only. In this case you won't be able to connect to the SQL Server as Windows authentication isn't supported with the gateways. You have to make sure your SQL server is supporting username and password authentication - a common user is the "sa" user. Regarding the username/password, please get in touch with your SQL Server Admin. -
Upgrade from SQL Server 2005 to SQL Server Express 2014 Enterprise
I was just wondering if it is possible to upgrade from SQL Server 2005 to SQL Server Express or will I have to build the environment and then migrate the database?
Thanks for any helpHi Lance_Romance,
As others’ posts, you don’t have to build new environment and then migrate databases between SQL Server instances, you can use the in-place upgrade strategy to upgrade from SQL Server 2005 to SQL Server 2014 .Please note that SQL Server 2005 SP4 is required
in this case.
Before upgrading , I recommend you to use
upgrade advisor, it can help to analyze your existing SQL Server deployment and inform you of issues that need to be addressed. In addition, please perform a full server backup prior to performing the in-place upgrade, which will be an important way
to revert your SQL Server to its previous state if the upgrade does not go as planned. For more details, please review this blog:
Upgrading to SQL Server 2014: A Dozen Things to Check.
Thanks,
Lydia Zhang -
Passing entire SQL query to BIP server from Forms
Hi
I want to pass the entire SQL statement or only a WHERE clause dynamically constructed on Forms side to BI Publisher server at runtime.
I have come across this article:
http://blogs.oracle.com/BIDeveloper/2009/12/dynamic_sql_query_in_data_template.html
It mentions about using pwhereclause which could be constructed dynamically.
Is it possible to pass the entire SELECT statement and has anyone done this before? May I have some tips on this?
Thanks and kind regards,
AparnaMy requirement is as follows:
1) I have a customised application which contains the definition of the report (report id, report name, the screen id on which the report is to appear as a record in the list and so on). This is where I would like to record the SQL statement which will be used to retrieve data for the report.
2) Once I launch the report from my application, it will pass SQL statement and other data (template, format, output file name, path where the output file will be saved, URL from which the output file will be launched after saving).
Thus, on BI Publisher server side, I shall only create a report, and will create a data template that will reference the SQL query that has been passed from application. I don't want to even specify parameters in Bi Publisher and want to specify them only in the application.
Is this possible?
Currently, I'm using a web service called 'PublicReportService' of BI Publisher to pass template, format, output file name, report path etc.). However, I am not sure how to pass an SQL query from Oracle Forms via this web service to BI Publisher.
Can someone please guide me?
Thanks and kind regards,
Aparna -
Passing PL/SQL Record to a Oracle Stored Procedure from Java.
Hi There.
Can someone let me know how to pass pl/sql records in java/oa framework. For E.g :
Package Specification:
create or replace package pkg is
type rec_type is record (n number, d date, v varchar2(1));
rec rec_type;
procedure p (r IN rec_type);
end ;
Package body :
create or replace package body pkg is
procedure p (r IN rec_type) is
begin
dbms_output.put_line('The values passed to the procedure are' || r.n||r.d||r.v);
end p ;
end pkg;
Actual pl/sql Call (I need counter part of below code in Java)
declare
r1 pkg.rec%type;
begin
r1.n := 7; r1.d := sysdate; r1.v := 'R';
pkg.p(r1); -- > How to do similar call using OracleCallableStatement
end;Hi
I am not sure whether you have check [this.|http://mukx.blogspot.com/2007/12/passing-plsql-table-to-java-using.html]
Thanks
Shailendra -
Passing PL/SQL varchar2 variable to XML Query
Hi guys,
i'm having trouble passing a pl/sql varchar2 variable to an XMLQuery.
This is the relevant part of my code:
DECLARE
lo_result XMLTYPE; --contains the XML which is being parsed below
lo_return XMLTYPE; -- for the XML result returned by XMLQuery
lo_start VARCHAR2 (100) DEFAULT 'Toronto'; -- a PL/SQL varchar2 variable
lo_end VARCHAR2 (100) DEFAULT 'Ottawa'; -- a PL/SQL varchar2 variable
BEGIN
SELECT XMLQUERY (
'for $i in //leg[start_address[text()[contains(.,$lo_start)]] and end_address[text()[contains(.,$lo_end)]]]/distance/value/text() return ($i)'
PASSING lo_result, lo_start AS "lo_start", lo_end AS "lo_end"
RETURNING CONTENT)
INTO lo_return
FROM DUAL;
END;The XPath expression is correct but it doesn't seem to accept my variables since lo_return is empty.
I think the variables should be of type Xmltype but the compiler won't let me convert them because they do not contain any XML tags .
Hope anyone can help.
Thanks,
Martinamay be i missed anything but
>
<start_address>Toronto, Ontario, Kanada</start_address>
<end_address>Huntsville, Alabama, Vereinigte Staaten</end_address>
>
and
>
lo_start VARCHAR2 (100) DEFAULT 'Toronto'; -- a PL/SQL varchar2 variable
lo_end VARCHAR2 (100) DEFAULT 'Ottawa'; -- a PL/SQL varchar2 variable
>
so
SQL> SELECT XMLQUERY (
2 'for $i in //leg[start_address[text()[contains(.,$lo_start)]] and end_address[text()[contains(.,$lo_end)]]]/distance/value/text() return ($i)'
3 PASSING
4 xmltype('<DirectionsResponse>
5 <status>OK</status>
6 <route>
7 <summary>I-75 N</summary>
8 <leg>
9 <duration>
10 <value>48220</value>
11 <text>13 Stunden, 24 Minuten</text>
12 </duration>
13 <distance>
14 <value>1404935</value>
15 <text>1.405 km</text>
16 </distance>
17 <start_location>
18 <lat>43.6533100</lat>
19 <lng>-79.3827700</lng>
20 </start_location>
21 <end_location>
22 <lat>34.7303300</lat>
23 <lng>-86.5860700</lng>
24 </end_location>
25 <start_address>Toronto, Ontario, Kanada</start_address>
26 <end_address>Huntsville, Alabama, Vereinigte Staaten</end_address>
27 </leg>
28 </route>
29 </DirectionsResponse>'),
30 'Toronto' AS "lo_start", 'Ottawa' AS "lo_end"
31 RETURNING CONTENT)
32 FROM DUAL;
XMLQUERY('FOR$IIN//LEG[START_A
SQL>
SQL>
SQL>
SQL> SELECT XMLQUERY (
2 'for $i in //leg[start_address[text()[contains(.,$lo_start)]] and end_address[text()[contains(.,$lo_end)]]]/distance/value/text() return ($i)'
3 PASSING
4 xmltype('<DirectionsResponse>
5 <status>OK</status>
6 <route>
7 <summary>I-75 N</summary>
8 <leg>
9 <duration>
10 <value>48220</value>
11 <text>13 Stunden, 24 Minuten</text>
12 </duration>
13 <distance>
14 <value>1404935</value>
15 <text>1.405 km</text>
16 </distance>
17 <start_location>
18 <lat>43.6533100</lat>
19 <lng>-79.3827700</lng>
20 </start_location>
21 <end_location>
22 <lat>34.7303300</lat>
23 <lng>-86.5860700</lng>
24 </end_location>
25 <start_address>Toronto, Ontario, Kanada</start_address>
26 <end_address>Huntsville, Alabama, Vereinigte Staaten</end_address>
27 </leg>
28 </route>
29 </DirectionsResponse>'),
30 'Toronto' AS "lo_start", /*'Ottawa'*/'Huntsville' AS "lo_end"
31 RETURNING CONTENT)
32 FROM DUAL;
XMLQUERY('FOR$IIN//LEG[START_A
1404935
SQL> -
HTTPS:\\ webserive call without passing certificate string
We are using HTTPS:\\ web service call from our one of the procedure.
When I did research, I found that, we can't call HTTPS:\\ web service without passing certificate.
My question is, how should I take care for situation where certificate got expired and need to replace certification.
I need some alternate way, where there is no need to pass certificate or no need to pass file path as well...Hello,
There was a similar question asked in our alternate forum, see: Access https URLs - SQLA Forum. Currently, certificates are specified manually. We have made an enhancement request for SQL Anywhere web clients to potentially use the OS Certificate store instead, in future versions.
So in summary, currently you will need to either replace the certificate, or provide an alternate certificate by specifying the certificate string in the stored procedure definition directly:
CREATE OR REPLACE PROCEDURE ...
CERTIFICATE '-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----'
Notably, MobiLink clients can currently use the (Windows or Android) operating system store for certificates if trusted_certificates is not specified at all.
Regards,
Jeff Albion
SAP Active Global Support -
How to open a page from a Form and pass parameters to the form on that page
I found a similar example on this forum, but it did not work for me:
declare
l_names owa.vc_arr;
l_values owa.vc_arr;
i number;
begin
PORTAL.wwpro_api_parameters.retrieve(l_names, l_values);
FOR i in 1..l_names.count
LOOP
htp.p(l_names(i) || ' ' || l_values(i));
END LOOP;
end;
By using this method i get the parameters for the Form, like the session ID, but not the parameters for the Page that the form is displayed in.
Another method I tried:
To open a Form from a Form and pass parameters works fine like this:
--In the After processing page PL/SQL event.
declare
v_id number;
blk varchar2(10):='DEFAULT';
Begin
v_id:=p_session.get_value_as_number (p_block_name=>blk,p_attribute_name=>'A_ID');
if v_id > 0 then
htp.formOpen('PORTAL.wwa_app_module.link?p_arg_names=_moduleid&p_arg_values=2649500412&p_arg_names=_show_header&p_arg_values=YES&p_arg_names=ID&p_arg_values='||to_char(v_id),'post');
htp.formSubmit(NULL,'Upload Files');
htp.formClose;
end if;
End;
But I want to open a Page containing the Form instead of just opening the Form. Is this possible to open a Page and pass paramters to the page, and then let the form inside the Page access the passed paramters. The reason for this is that a Form cannot be based on a page template, or can it? When opening the form i want to keep the left menu, which I can if it is a page based on my template with the left menu.
Best regards
HalvorHi,
You can do this by calling the url of the page with the form. You can then use p_arg_names and p_arg_values to pass parameters. In the called form you can get the value from p_arg_names and p_arg_values and assign it to the form field.
You can call this code in the success procedure of the calling form.
declare
v_id number;
blk varchar2(10):='DEFAULT';
v_url varchar2(2000);
Begin
v_id:=p_session.get_value_as_number (p_block_name=>blk,p_attribute_name=>'A_ID');
v_url := <page_url>;
if v_id > 0 then
call(v_url||'&p_arg_names=id&p_arg_values='||v_id);
end if;
End;
In the called form in "Before displaying form" plsql section write this code.
for i in 1..p_arg_names.count loop
if p_arg_names(i) = 'id' then
p_session.set_value(
p_block_name => blk,
p_attribute_name => 'A_ID',
p_value => p_arg_values(i)
end if;
end loop;
This code picks up the value from p_arg_values and assigns it to the form field.
Hope that helps.
Thanks,
Sharmila -
Get site id in WCS jsp without using ics.SQL
Hi,
Is there a way i can get siteId of my current site in JSP without using ics.SQL tags and getting it from publication table
We are trying to implemet a lucene search for loading assets present in current site only.
Thanks in advance for your help.Use the below code to get it.
<publication:load name="thisPub" field="name" value='<%=ics.GetVar("site") %>'/>
<publication:get name="thisPub" field="id" output="thisPubID"/>
Dont forget to import publication.tld
Regards,
Ravi G -
How to skip first 5 lines from a txt file when using sql*loader
Hi,
I have a txt file that contains header info tat i dont need. how can i skip those line when importing the file to my database?
CheersDanny Fasen wrote:
I think most of us would process this report using pl/sql:
- read the file until you've read the column headers
- read the account info and insert the data in the table until you have read the last account info line
- read the file until you've read a new set of column headers (page 2)
- read the account info and insert the data in the table until you have read the last account info line (page 2)
- etc. until you reach the total block idenfitied by Count On-line ...
- read the totals and compare them with the data inserted in the tableOr maybe like this...
First create an external table to read the report as whole lines...
SQL> ed
Wrote file afiedt.buf
1 CREATE TABLE ext_report (
2 line VARCHAR2(200)
3 )
4 ORGANIZATION EXTERNAL (
5 TYPE oracle_loader
6 DEFAULT DIRECTORY TEST_DIR
7 ACCESS PARAMETERS (
8 RECORDS DELIMITED BY NEWLINE
9 BADFILE 'bad_report.bad'
10 DISCARDFILE 'dis_report.dis'
11 LOGFILE 'log_report.log'
12 FIELDS TERMINATED BY X'0D' RTRIM
13 MISSING FIELD VALUES ARE NULL
14 REJECT ROWS WITH ALL NULL FIELDS
15 (
16 line
17 )
18 )
19 LOCATION ('report.txt')
20 )
21 PARALLEL
22* REJECT LIMIT UNLIMITED
SQL> /
Table created.
SQL> select * from ext_report;
LINE
x report page1
CDC:00220 / Sat Aug-08-2009 xxxxp for 02/08/09 - 08/08/09 Effective Date 11/08/09 Wed Sep-30-2009 08:25:43
Bill to
Retailer Retailer Name Name on Bank Account Bank ABA Bank Acct On-line Amount Instant Amount Total Amount
======== ============================== ============================== ========== ==================== =============== =============== ===============
0100103 BANK Terminal raji 123456789 123456789 -29,999.98 9 0.00 99 -29,999.98
0100105 Independent 1 Savings 123456789 100000002 -1,905.00 9 0.00 99 -1,905.00
0100106 Independent 2 system 123456789 100000003 -800.00 9 -15.00 99 -815.00
LARGE SPACE
weekly_eft_repo 1.0 Page: 2
CDC:00220 / Sat Aug-08-2009 Weekly EFT Sweep for 02/08/09 - 08/08/09 Effective Date 11/08/09 Wed Sep-30-2009 08:25:43
Bill to
Retailer Retailer Name Name on Bank Account Bank ABA Bank Acct On-line Amount Instant Amount Total Amount
======== ============================== ============================== ========== ==================== =============== =============== ===============
Count On-line Amount Instant Amount Total Amount
============== ====================== ====================== ======================
Debits 0 0.00 0.00 0.00
Credits 3 -32,704.98 -15.00 -32,719.98
Totals 3 -32,704.98 -15.00 -32,719.98
Total Tape Records / Blocks / Hash : 3 1 37037034
End of Report
23 rows selected.Then we can check we can just pull out the lines of data we're interested in from that...
SQL> ed
Wrote file afiedt.buf
1 create view vw_report as
2* select line from ext_report where regexp_like(line, '^[0-9]')
SQL> /
View created.
SQL> select * from vw_report;
LINE
0100103 BANK Terminal raji 123456789 123456789 -29,999.98 9 0.00 99 -29,999.98
0100105 Independent 1 Savings 123456789 100000002 -1,905.00 9 0.00 99 -1,905.00
0100106 Independent 2 system 123456789 100000003 -800.00 9 -15.00 99 -815.00And then we adapt that view to extract the data from those lines as actual columns...
SQL> col retailer format a10
SQL> col retailer_name format a20
SQL> col name_on_bank_account format a20
SQL> col online_amount format 999,990.00
SQL> col instant_amount format 999,990.00
SQL> col total_amount format 999,990.00
SQL> ed
Wrote file afiedt.buf
1 create or replace view vw_report as
2 select regexp_substr(line, '[^ ]+', 1, 1) as retailer
3 ,trim(regexp_replace(regexp_substr(line, '[[:alpha:]][[:alnum:] ]*[[:alpha:]]', 1, 1), '(.*) +[^ ]+$', '\1')) as retailer_name
4 ,trim(regexp_replace(regexp_substr(line, '[[:alpha:]][[:alnum:] ]*[[:alpha:]]', 1, 1), '.* ([^ ]+)$', '\1')) as name_on_bank_account
5 ,to_number(regexp_substr(regexp_replace(line,'.*[[:alpha:]]([^[:alpha:]]+)','\1'), '[^ ]+', 1, 1)) as bank_aba
6 ,to_number(regexp_substr(regexp_replace(line,'.*[[:alpha:]]([^[:alpha:]]+)','\1'), '[^ ]+', 1, 2)) as bank_account
7 ,to_number(regexp_substr(regexp_replace(line,'.*[[:alpha:]]([^[:alpha:]]+)','\1'), '[^ ]+', 1, 3),'999,999.00') as online_amount
8 ,to_number(regexp_substr(regexp_replace(line,'.*[[:alpha:]]([^[:alpha:]]+)','\1'), '[^ ]+', 1, 5),'999,999.00') as instant_amount
9 ,to_number(regexp_substr(regexp_replace(line,'.*[[:alpha:]]([^[:alpha:]]+)','\1'), '[^ ]+', 1, 7),'999,999.00') as total_amount
10* from (select line from ext_report where regexp_like(line, '^[0-9]'))
SQL> /
View created.
SQL> select * from vw_report;
RETAILER RETAILER_NAME NAME_ON_BANK_ACCOUNT BANK_ABA BANK_ACCOUNT ONLINE_AMOUNT INSTANT_AMOUNT TOTAL_AMOUNT
0100103 BANK Terminal raji 123456789 123456789 -29,999.98 0.00 -29,999.98
0100105 Independent 1 Savings 123456789 100000002 -1,905.00 0.00 -1,905.00
0100106 Independent 2 system 123456789 100000003 -800.00 -15.00 -815.00
SQL>I couldn't quite figure out the "9" and the "99" data that was on those lines so I assume it should just be ignored. I also formatted the report data to fixed columns width in my external text file as I'd assume that's how the data would be generated, not that that would make much difference when extracting the values with regular expressions as I've done.
So... something like that anyway. ;) -
I have a variable that contains a formula, eg.
V_FORMULA varchar2(200) := '5 * 50 + 200';
I want to assign the result of the formula into another variable, without using a DB call with SQL.
eg.
V_RESULT number;
V_RESULT := DBMS_surprise_package(V_FORMULA);
I want V_RESULT to be 450 after the statement is executed.
Is that possible?? Is there such a package in PLSQL?
I think the Forms NAME_IN package did something similar.970779 wrote:
I guess I'll just have to rewrite it using execute immediate with bind variables to stop the shared pool getting filled up with thousands of these statements, since none of you have a non-db solution.Write your own if the expressions are simple enough...
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_formula varchar2(200) := '5 * 50 + 200';
3 l_result number := 0;
4 tok varchar2(100);
5 op varchar2(100);
6 function get_token(str in out varchar2) return varchar2 is
7 begin
8 tok := trim(regexp_substr(str,'^[0-9]+|[^0-9]+'));
9 str := trim(regexp_replace(str,'^([0-9]+|[^0-9]+)'));
10 return tok;
11 end;
12 begin
13 loop
14 tok := get_token(l_formula);
15 exit when tok is null;
16 if tok in ('*','+','-','/') then
17 op := tok;
18 else
19 case op when '*' then l_result := l_result * to_number(tok);
20 when '+' then l_result := l_result + to_number(tok);
21 when '-' then l_result := l_result - to_number(tok);
22 when '/' then l_result := l_result / to_number(tok);
23 else l_result := to_number(tok);
24 end case;
25 end if;
26 end loop;
27 dbms_output.put_line(l_result);
28* end;
SQL> /
450
PL/SQL procedure successfully completed.:D
Maybe you are looking for
-
How to get iTunes 10 back on Mac OS 10.8.x?
Hello, When I upgraded my system, MacOS overwrote my iTunes with 11.04 which for me is a big step back in ease of use. Is there anywhere an option to download an older iTunes (10.x) somewhere and overwrite this nasty new one under 10.8.4? Any help wo
-
Widescreen looks zoomed in on tv
I've created a film in FCE 4. It wasn't filmed in widescreen, but changed to it in FCE on the timeline properties. I've exported>quicktime movie>not self-contained. Open the file in Quicktime Pro>window>show movie properties>video track, selected to
-
How do i get into my ipod touch when forgoten password
i cant get into my ipod because i forgotmy password but my ipod wount show up on itunes please help me fix it thank u
-
How to make a sales order item deleted in ECC while in CRM just status changed?
Hi expert, I have a requirment, that is: 1. the user will change the USER STATUS in a line item of sales order to "CANCEL". 2. When the order was replicated to ECC,the item should be deleted totally and the ITEM in CRM should not be affected. How can
-
What is the best app for creating and signing documents on the iPad?
I am a home organizer and I am typically in a clients home when I need to have them sign a contract and I want to become a 'paperless' organizer. I need to take my service agreement, enter their information, have them sign the document and then emai