Function as column in select query
Recently I came upon a couple of applications using Oracle database 10g that use functions as a column in a select query for reporting purposes. These queries were taking about 10 minutes to return 55,000 records. How can such queries be optimized where the functions in the queries cannot be modified?
Can the performance be improved at all without a re-design of the query?
SELECT
col1
,col2
,fn_get_val(col3)
,col4
,col5
FROM
table a,
table b
WHERE .....; The above function "fn_get_val" is defined as:
CREATE OR REPLACE fn_get_val(i_col IN VARCHAR2) return varchar2
as
CURSOR c ( i_var VARCHAR2 )
business logic here again
begin
OPEN c( i_col );
LOOP
Loop through the above cursor
EXIT; -- exit when condition satisfied.
END LOOP;
CLOSE c;
end;
/Thanks in advance!
user1980 wrote:
Can the performance be improved at all without a re-design of the query?Possibly if function is deterministic.
Simplistic example:
SQL> create or replace package Global as
2 counter integer := 0;
3 end;
4 /
Package created.
SQL>
SQL> --// non-deterministic
SQL> create or replace function EmpName( empID number ) return varchar2 is
2 cursor c is
3 select ename from emp where empno = empID;
4 empName varchar2(10);
5 begin
6 Global.counter := Global.counter + 1;
7 --// simulating your explicit cursor loop
8 open c;
9 fetch c into empName;
10 close c;
11
12 return(
13 InitCap(empName)
14 );
15 end;
16 /
Function created.
SQL>
SQL>
SQL> exec Global.counter := 0;
PL/SQL procedure successfully completed.
SQL> select
2 empName( 7369 ) as NAME
3 from dual
4 connect by level <= 100;
NAME
Smith
Smith
100 rows selected.
SQL> exec dbms_output.put_line( 'Counter='||Global.counter );
Counter=100
PL/SQL procedure successfully completed.
SQL>
SQL> --// deterministic
SQL> create or replace function EmpName( empID number ) return varchar2 deterministic is
2 cursor c is
3 select ename from emp where empno = empID;
4 empName varchar2(10);
5 begin
6 Global.counter := Global.counter + 1;
7 --// simulating your explicit cursor loop
8 open c;
9 fetch c into empName;
10 close c;
11
12 return(
13 InitCap(empName)
14 );
15 end;
16 /
Function created.
SQL>
SQL> exec Global.counter := 0;
PL/SQL procedure successfully completed.
SQL> select
2 empName( 7369 ) as NAME
3 from dual
4 connect by level <= 100;
NAME
Smith
Smith
100 rows selected.
SQL> exec dbms_output.put_line( 'Counter='||Global.counter );
Counter=1
PL/SQL procedure successfully completed.
SQL> So 1 execution of the function versus a 100 executions. But it is not always that straightforward and simplistic.
The ideal would be to not use a user function in the first place - but to instead apply that function's logic directly in SQL using native SQL statements.
Similar Messages
-
Facing problem with a date column in select query
Hi,
I am facing problem with a date column. Below is my query and its fainling with " invalid number format model" .
Query: SELECT *
FROM EMP
WHERE trunc(LAST_UPDATED) >= to_date(to_char(22-05-2009,'dd-mm-yyyy'),'dd-mm-yyyy')
LAST_UPDATED column is "DATE" data type.
Please help me ThanksRadhakrishna Sarma wrote:
SeánMacGC wrote:
WHERE LAST_UPDATED >= to_date('22-05-2009','dd-mm-yyyy');
You do not need the TRUNC here in any case.
I don't think so. What if the user wants only data for 22nd May and the table has records with date later than 22nd also? In that case your query willl not work. In order for the Index to work, I think the query can be written like this I think Sean is right though. Use of TRUNC Function is quiet useless based on the condition given here, since the to_date Function used by OP will always point to midnight of the specified date, in this case 22-05-2009 00:00:00.
Regards,
Jo
Edit: I think Sean proved his point... ;) -
Can i update more then one column using select query.
Dear All,
Can i update more then one column of target table A from source table B. Like
Update table A set A.A1 = (Select B.B1 from B where A.A3 = B.B3).
Above stmt. I am updating only one column. But I want to update more then one column A.A1 and A.A2
Plz give me the possible ways.
Thanks,
VikasYes you can do. Try the below Query
Update A set (A.A1,A.A2) = (Select B.B1,B.B2 from B where A.A3 = B.B3) -
COMBINING COMMON COLUMNS IN SELECT QUERY
hi all,
While make inner join between two tables how to link more than one
common colums , which operator i want to use, shall anybody give me one ex.
Thanks in advance.
R.Vijaihi
good
try like this
SELECT c~matnr "Material no.
c~werks "Plant
c~lvorm "Flag Mat.-Del. at Plant level
c~bwtty "Valuation category
c~kzkri "Indicator: Gritical part
c~dispr "Material: MRP profile
ADD Mike Krepcik TD 3363 02/01/05 D10K913640
c~dismm "MRP type
END TD 3363 02/01/05 D10K913640
c~plifz "Planned delivery time in days
c~perkz "Period indicator
c~minbe "Reorder point
c~mabst "Maximum stock level
c~umlmc "Stock in Tran. (plant to plant)
a~mtart "Material type
a~meins "Base unit of measure
k~spras "Language key
k~maktx "Material description
w~bwkey "Valuation area
w~bwtar "Valuation type
w~lbkum "Total value stock
w~salk3 "Value of total valuated stock
w~verpr "Moving ave. price/periodic unit
w~peinh "Price unit ADD D10K913194
FROM marc AS c LEFT OUTER JOIN mara AS a
ON cmatnr = amatnr
LEFT OUTER JOIN makt AS k
ON cmatnr = kmatnr
LEFT OUTER JOIN mbew AS w
ON cmatnr = wmatnr AND
cwerks = wbwkey
INTO TABLE i_splus
WHERE c~matnr IN s_matnr "Material no.
AND c~werks IN s_werks. "Plant
thanks
mrutyun^ -
How to create a Type Object with Dynamic select query columns in a Function
Hi Every One,
I'm trying to figure out how to write a piplined function that executes a dynamic select query and construct a Type Object in order to assigned it to the pipe row.
I have tried by
SELECT a.DB_QUERY INTO actual_query FROM mytable a WHERE a.country_code = 'US';
c :=DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c,actual_query,DBMS_SQL.NATIVE);
l_status := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
FOR j in 1..col_cnt LOOP
DBMS_SQL.DEFINE_COLUMN(c,j,v_val,2000);
END LOOP;
FOR j in 1..col_cnt LOOP
DBMS_SQL.COLUMN_VALUE(c,j,v_val);
END LOOP;
But got stuck, how to iterate the values and assign to a Type Object from the cursor. Can any one guide me how to do the process.
Thanks,
mallikj2Hi Justin,
First of thanks for your reply, and coming to my requirement, I need to report the list of items which are there in the dynamic select statement what am getting from the DB. The select statement number of columns may vary in my example for different countries the select item columns count is different. For US its '15', for UK it may be 10 ...like so, and some of the column value might be a combination or calculation part of other table columns (The select query contains more than one table in the from clause).
In order to execute the dynamic select statement and return the result i choose to write a function which will parse the cursor for dynamic query and then iterate the values and construct a Type Object and append it to the pipe row.
Am relatively very new for these sort of things, welcome in case of any suggestions to make it simple (Instead of the function what i thought to work with) also a sample narrating the new procedure will be appreciated.
Thanks in Advance,
mallikj2. -
Supress the ROW_ID column in the Select Query.
Hi,
I have one custom form and from main form I am calling the Line Form.
But when I am clicking the LINE button then Form is getting open but it is giving one Error message like
FRM-40505: Oracle Error:unable to perform query
Once I check the Detail error.
it is giving me this message.
ORA-00904: "ROW_ID": invalid identifier
And I checked the query my query is returning the ROW_ID column.
Please help on Suppressing the Row_id column getting selected from the query.
Thanks
NiharHi Nihar;
Please see:
Transactions Workbench Error: Listing of FRM Errors [ID 1321612.1]
Regard
Helios -
Cursor in select query in row to column format
Hi
I have the query like below
SELECT d.department_id,
CURSOR(SELECT e.first_name,
e.last_name
FROM employees e
WHERE e.department_id = d.department_id
) emps
FROM depatments dI want the result set in a format of Row To columns like
10 20
<cursor result> <cursor result>pls give ur suggestions how to achieve this in a efficient way?I tried the method of "max(decode(.." but dont think so its possible with thisvishnu prakash wrote:
Hi
I have the query like below
SELECT d.department_id,
CURSOR(SELECT e.first_name,
e.last_name
FROM employees e
WHERE e.department_id = d.department_id
) emps
FROM depatments dI want the result set in a format of Row To columns like
10 20
<cursor result> <cursor result>pls give ur suggestions how to achieve this in a efficient way?I tried the method of "max(decode(.." but dont think so its possible with thisNumber of column of a select query is static. Must be known at the parsing time itself. But in your case i dont think the number of columns will be limited to 2 (10 and 20) there could be many more.
You can search this forum to see how to PIVOT your data. There are lot of example. You can also try dynamic pivot. Its all in here, just search. -
Column order in a select * query
Suppose I have 256 columns in a table and if I query select * from tablename ,what will the column order in the result.Will this be always same as order as in created statement?
If the columns were all in the original CREATE TABLE statement, then, yes, the ordering of columns in SELECT * FROM will match the order from the CREATE TABLE statement.
If columns were added after the initial create, then the original columns will come first (in their order) and then the added columns (in their order), etc.
In the real world, it is a very bad practice to use SELECT * and have expectations about the ordering of the columns. Consider this scenario:
Table T was created and implemented in production a year ago with columns A, B, C
A project started up three months ago and added column D but the project is stalled in development. So in development T had columns A, B, C, D
Later, another project started up and added columns E and F. Unlike the other project, it has progressed to Test. and Production. So in Development the table has columns A, B, C, D, E, F. In test and production the table has columns A, B, C, E, F.
Now that stuck project has progressed to Test and Production. Now T has columns A, B, C, E, F, D in test and production but still A, B, C, D, E, F in development.
Until someone notices and decides to fix it (where and how?)
Be very, very careful about using SELECT *. -
Unknown Column Name "XYZ" not detemined untill runtime.Select query.
Hi,
I have written a query in ABAP.I am getting following error.Can some one help me resolve this.There is a column "LANDX" in standard table T005 of PI which i need to get values from. The problem is that the column is visible only at runtime and not otherwise.How can i fetch data from this coulmn writing a select query for this.
Query written is:
SELECT landx from T005 into table it_t005.
Error:
"Unknown column name "XYZ" not determined untill runtime,you cannot specify a field list."Hi Deepika u were right. that there is a landx field but it is included in that table.
so u cant exactly get it.
now u can get ur country name and iso code just like this.
tables: t005t , t005.
data: BEGIN OF it OCCURS 100,
landx like t005t-landx,
intca like t005-intca,
END OF it.
SELECT t005t~landx t005~intca into CORRESPONDING FIELDS OF TABLE it
from T005t
INNER JOIN t005 on ( t005t~land1 = t005~land1 ).
it is fulfilling ur need.
Edited by: Matt on Feb 3, 2009 7:49 AM - Please don't use txtspk -
Hi All,
The Actual query to perform is below.
SELECT name,number from emp WHERE CASE WHEN :1='T' AND term_date IS Not NULL THEN 1 WHEN :1='A' AND term_date IS NULL THEN 1 WHEN :1='ALL' THEN 1 ELSE 1 END = 1;
I have tried in DB adapter like below as a parameter for :1 as #vInputParam
SELECT name,number from emp WHERE CASE WHEN #vInputParam='T' AND term_date IS Not NULL THEN 1 WHEN #vInputParam='A' AND term_date IS NULL THEN 1 WHEN #vInputParam='ALL' THEN 1 ELSE 1 END = 1;
Getting Error code :17003 .java.sql.SQLException: Invalid column index error.
Please suggest me on using ':' bind character in DB adapter Select Query SOA11g.
Can someone help me on this please?
Thanks,
HariHi,
Could you please make sure your binding style(Oracle Positional,Oracle named..etc) of the Seeded VO and Custom Vo are same.
This is the option you will get when you are extending your vo. So make sure that both are same.
You can refer the below link too
VO extension leads to "Invalid column index" exception
Thanks
Bharat -
Calling an pipeline function in a Select query
Hello gurus ,
i have a query calling pipeline function
WITH t AS
(SELECT dep_code, emp_id
FROM test1
WHERE dep_code = 'C1' AND emp_id = '123')
SELECT *
FROM TABLE
(CAST
((pk_get_emp_dtls.fn_t_get_emp_dtls (t.dep_code,
t.empid,
TRUNC (SYSDATE)
) AS ps_ot_emp_dtls
t;in this above query i want to use the emp id ,dept code from the with clause as parameters in the function pk_get_emp_dtls.fn_t_get_emp_dtls
but error occures SQL command not ended properly
Regards,
Friend
Edited by: most wanted!!!! on Nov 14, 2012 6:17 AMI see Solomon beat me to it...
SQL> create or replace type o_emp as object (empno number, ename varchar2(10))
2 /
Type created.
SQL>
SQL> create or replace type t_emp as table of o_emp
2 /
Type created.
SQL>
SQL> create or replace function get_emp(p_deptno in number) return t_emp pipelined as
2 v_emp o_emp := o_emp(null,null);
3 cursor cur_emp is
4 select empno, ename
5 from emp
6 where deptno = p_deptno;
7 begin
8 for i in cur_emp
9 loop
10 v_emp.empno := i.empno;
11 v_emp.ename := i.ename;
12 pipe row (v_emp);
13 end loop;
14 return;
15 end;
16 /
Function created.
SQL>
SQL>
SQL> with t as (select deptno from dept where dname = 'SALES')
2 select x.*
3 from t, table(get_emp(t.deptno)) x
4 /
EMPNO ENAME
7499 ALLEN
7521 WARD
7654 MARTIN
7698 BLAKE
7844 TURNER
7900 JAMES
6 rows selected.
SQL> with t as (select deptno from dept where dname = 'SALES')
2 select x.*
3 from table(get_emp(t.deptno)) x, t
4 /
from table(get_emp(t.deptno)) x, t
ERROR at line 3:
ORA-00904: "T"."DEPTNO": invalid identifier -
Call the Function against a select query in 500 procedures...
Hello Gurus,
I have a scenario, where i had made one function(UDF Function) to calculate something and in every procedure i call that function and calculate my requirement.
Yesterday, i made a select query using reg exp for the same calculation..
So my question is, what should be the proper approach..
I need to implement this on 500 procedures...
And the UDF function is
CREATE OR REPLACE FUNCTION "UDF_TEXTSPLIT" (
p_list VARCHAR2,
p_del VARCHAR2 := ','
) RETURN split_tbl pipelined
IS
l_idx PLS_INTEGER;
l_list VARCHAR2(7999) ;
l_value VARCHAR2(7999);
BEGIN
l_list := p_list;
LOOP
l_idx := INSTR(l_list,p_del);
IF l_idx > 0 THEN
pipe ROW(SUBSTR(l_list,1,l_idx-1));
l_list := SUBSTR(l_list,l_idx+LENGTH(p_del));
ELSE
pipe ROW(l_list);
EXIT;
END IF;
END LOOP;
RETURN;
END Udf_Textsplit;
I have made this query:
SELECT a.b,z. b1 FROM
(SELECT ROWNUM d,REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) b
FROM (SELECT 'xxx>zzz>gg' str1 FROM dual)
CONNECT BY REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) IS NOT NULL)a,
(SELECT ROWNUM d,REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) b1
FROM (SELECT '100>500>20' str1 FROM dual)
CONNECT BY REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) IS NOT NULL)z
WHERE a.d=z.d
Do i use the same select query in all 500 procedures or call the (UDF Function) in every procedure..
So which will be faster...
Your approach would be very much appreciated...
Thanks,
Haraprasad...Hmm, do I edit 500 procedures to replace a function call with a SQL statement, or edit 1 function to use a sql statement instead of the current algorithm?
This is why we use code modules that do one thing and do it well. As long as the new version of the function takes the same arguments and returns the same results as the old, then the callers will never know that the way the function works has changed.
Whenther you put the select statement in 500 procedures, or 1 function, there will still be a context switch every time you use it. The tiny additional overhead of calling a function before the context switch would be unnoticeable.
John -
Select query output as a separate column
Hi,
How to represent the different values in the same table column as an output in the separate columns using the select query ?
For example,
Table "A" has column "col1"
col1 contains values as below:
col1
====
1
2
3
4
5
now want to display the above column values as a separate column as the output.
col_alias1 col_alias2 col_alias3 col_alias4 col_alias5
1 2 3 4 5
How it can be done ?
Regards
Edited by: user640001 on Jan 31, 2011 11:19 PMHi,
You can try something mentioned in this link.
http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php
or try this
with t as (
select 'PID12' as product_id, 1 as status_id, 'Time1' as time from dual union all
select 'PID13', 2, 'Time2' as time from dual union all
select 'PID14', 3, 'Time3' as time from dual)
select min(case when status_id = 1 then product_id || ' ' || time end) as Recieved, min(case when status_id = 2 then product_id || ' ' || time end) as Accepted,
min(case when status_id = 3 then product_id || ' ' || time end) as Delivered from tcheers
VT
Edited by: VT on Feb 1, 2011 5:28 PM -
How to implement 'Quick Select' column in a query result table?
Hi,
I have a requirement in OAF to design a search page with 'Quick select' column.
One of the column in the query result table should be a quick select.
Once user clicks on the quick select column, we have to navigate back to the previous page with the row value selected.
Can anyone help me in this.
Thanks.Also refer the search exercise in the toolbox tutorials.
you can implement the quick search in the same way as update and delete buttons.
--Prasanna -
Convert columns to rows by a select query
I have a table with 10 columns. Pk is combination of 3 columns, let us say A, B and C. I need a select query which returns 7 rows with four columns each let us say A,B,C and D where D contains the value of non PK column. i.e. for first row, D will contain value of fourth column of the table, for second row, D will contain fifth column of the table and so on.
Please help.Maybe NOT TESTED!
select col_a,col_b,col_c,column_4 col_d
from (select col_a,col_b,col_c,col_d,col_e,col_f,col_g,col_h,col_i,col_j
from the_table
unpivot include nulls (column_4 for source_column in (col_d as 'col_d',
col_e as 'col_e',
col_f as 'col_f',
col_g as 'col_g',
col_h as 'col_h',
col_i as 'col_i',
col_j as 'col_j'
)Regards
Etbin
Maybe you are looking for
-
How do I watch my iTunes movies, tv shows on my mac without having to download them all to my HD? I really want my Mac to function like my Apple TV since I have just moved and don't have my TV for another few weeks. Since I purchased my three Apple
-
CS5.5 Phonegap - Anchor Tags Don't Work
So I made a test Android app using the phonegap template and it seemed to work okay. Now I'm trying to add anchor tags to link a table of contents from the top to text found lower on the page like this: <a href="#cq">Clinical Question</a> <a id="cq">
-
I recently had a hard drive failure on my iMac. A new 1TB hard drive was installed along with OS X 10.6.8. Since restoring files from Time Machine, I am unable to open .docx files using MS Word 2011. I receive a 'convert file' dialog box. I can o
-
Hello everyone I lost all my purchased applications on my iPhone 4. After I connected my phone to the PC, message appeared on iTunes asking me whether I want to transfer all my purchased applications to the PC or not, so I chose "Transfer". The phone
-
Hi, I'm sure this question has been answered before but I can't find it. My girlfriend has an iPod mini, and I want to put audible content from my PC on it. Is this do-able? Thanks, Bruce