Function Compilation
Hi All,
Some one told me in Oracle, Function is compiled at runtime,whenever we call function, in our procedure or select statement.
Is it true....?
Regards
Anand
Hi Anand,
Read the block *"Better Performance"* to clear your doubt in the following link,
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/overview.htm#i8854
Twinkle
Similar Messages
-
User defined java function-compilation error! Activation cancelled
Hi all!
I have written an User defined Function in java for converting XML to PDF which is available at this blog:
/people/divya.vidyanandanprabhu/blog/2005/06/28/converting-xml-to-pdf-using-xi
I added both dom4j-1.6.1.jar and itext-1.4.1.jar files in (XIserver machine)D:/usr/sap/....server0/bin.
When i try to activate in IR, i got the following error.
Activation of the change list canceled Check result for Message Mapping test | http://httpadp.com/send: Starting compilation Source code has syntax error: D:/usr/sap/QN7/DVEBMGS00/j2ee/cluster/server0/./temp/classpath_resolver/Map7bf962e0f21411daae8a00111120e6db/source/com/sap/xi/tf/_test_.java:3: package com.xml2pdf does not exist import com.sap.aii.mappingtool.tf3.;import com.sap.aii.mappingtool.tf3.rt.;import java.util.;import java.io.; import java.lang.reflect.*;import com.xml2pdf.XmlToPdf; ^ D:/usr/sap/QN7/DVEBMGS00/j2ee/cluster/server0/./temp/classpath_resolver/Map7bf962e0f21411daae8a00111120e6db/source/com/sap/xi/tf/_test_.java:51: cannot resolve symbol symbol : class XmlToPdf location: class com.sap.xi.tf._test_ XmlToPdf x = new XmlToPdf("D:
qf
source
Input.xml", "D:
qf
target
Output.pdf"); ^ D:/usr/sap/QN7/DVEBMGS00/j2ee/cluster/server0/./temp/classpath_resolver/Map7bf962e0f21411daae8a00111120e6db/source/com/sap/xi/tf/_test_.java:51: cannot resolve symbol symbol : class XmlToPdf location: class com.sap.xi.tf._test_ XmlToPdf x = new XmlToPdf("D:
qf
source
Input.xml", "D:
qf
target
Output.pdf");Hi
My java program is:
import com.xml2pdf.XmlToPdf;
public String testing(String a,String b,String c,Container container){
XmlToPdf x = new XmlToPdf("D:
qf
source
Input.xml", "D:
qf
target
Output.pdf");
x.Convet();
return "";
Can you please figureout any errors in my prg.
I have imported the 2(itext-1.4.1 and dom4j-1.6.1) jars into Imported Archives in my scenario in IR.
I placed these jars in D:/usr/sap/..../server0/bin
also. I followed the blog thoroughly and carefully.
Thanks a lot for your suggestion. -
Please help me I don't know much about PLSQL FUNCTION
I am getting fallowing error while compiling the function
ine # = 3 Column # = 8 Error Text = PLS-00201: identifier 'MYVARCHARTABLE' must be declared
where to declere and how to declere the MYVARCHARTABLE
CREATE OR REPLACE FUNCTION "STR2TBL" ( p_str in
varchar2)
return myVarcharTable
as
l_str long default p_str || ',';
l_n number;
l_data myVarcharTable := myVarcharTable();
begin
loop
l_n := instr( l_str, ',' );
exit when (nvl(l_n,0) = 0);
l_data.extend;
l_data(l_data.count) := ( ltrim(rtrim(substr(l_str,1,l_n-1))) );
l_str := ltrim( substr( l_str, l_n+1 ) );
end loop;
return l_data;
end;Hi,
This will give a clear idea about how to return an array from a PL/SQL Stored function.
http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/varray/index.html
Thanks, -
Function compilation errors?
In sys schema the status of a functions get_domain_index_tables and get_operated_qty is shown invalid. I'm continuously trying to get errors but in vain. Recompilation is always successsful with compilation errors.
HELP please.Simple Idea:
If your function in the Package, try to compile just Package Header first
(You can copy & paste from your script) and then do
SHOW ERRORS; or SELECT * FROM USER_ERRORS;
If any Errors, fix them, compile again.
(Package body won't compile without Errors until header is compiled without them)
Then try to compile Package Body ALTER PACKAGE TEST_PKG COMPILE BODY;
and query again (SHOW ERRORS; or SELECT * FROM USER_ERRORS;) -
This Formula(Function) compiles but does not display any result
Please can anybody help me resolve this issue.The code below is a code for a formula(function) column in oracle report, i have complied this code and it successfully complied but it does not display any result for the column having a stock balance in the entire report.
function CF_STOCK_BALFormula return Number is
v_all_positive NUMBER;
v_all_negative NUMBER;
begin
IF :transaction_type IN ('RECEIPT', 'RETURN') THEN
IF :cp_stock_bal IS NULL OR :cp_stock_bal = 0 THEN
:cp_stock_bal := :opening_balance + :cp_stock_bal + :quantity;
ELSE
:cp_stock_bal := :cp_stock_bal + :quantity;
END IF;
ELSIF :transaction_type IN ('ISSUE') THEN
IF :cp_stock_bal IS NULL OR :cp_stock_bal = 0 THEN
:cp_stock_bal := :opening_balance + :cp_stock_bal - :quantity;
ELSE
:cp_stock_bal := :cp_stock_bal - :quantity;
END IF;
END IF;
RETURN (:cp_stock_bal);
end;
Edited by: Gbenga on Jan 17, 2012 11:30 PMPlease can anybody help me resolve this issue.The code below is a code for a formula(function) column in oracle report, i have complied this code and it successfully complied but it does not display any result for the column having a stock balance in the entire report.
function CF_STOCK_BALFormula return Number is
v_all_positive NUMBER;
v_all_negative NUMBER;
begin
IF :transaction_type IN ('RECEIPT', 'RETURN') THEN
IF :cp_stock_bal IS NULL OR :cp_stock_bal = 0 THEN
:cp_stock_bal := :opening_balance + :cp_stock_bal + :quantity;
ELSE
:cp_stock_bal := :cp_stock_bal + :quantity;
END IF;
ELSIF :transaction_type IN ('ISSUE') THEN
IF :cp_stock_bal IS NULL OR :cp_stock_bal = 0 THEN
:cp_stock_bal := :opening_balance + :cp_stock_bal - :quantity;
ELSE
:cp_stock_bal := :cp_stock_bal - :quantity;
END IF;
END IF;
RETURN (:cp_stock_bal);
end;
Edited by: Gbenga on Jan 17, 2012 11:30 PM -
can someone please assist
CREATE OR REPLACE FUNCTION HR.is_leap_year ( date_in IN DATE)
RETURN NUMBER
AS
result NUMBER := 0;
BEGIN
SELECT
CASE WHEN (
MOD(EXTRACT(YEAR FROM date_in), 4) = 0 AND MOD(EXTRACT(YEAR FROM date_in) ,100) != 0)
OR MOD(date_in, 400) = 0 THEN 1 ELSE 0 END AS bit
INTO result
FROM DUAL;
RETURN result;
END is_leap_year ;
/ricard888 wrote:
can someone please assistDo not use SQL when SQL is not needed - context switching from the PL/SQL engine to the SQL engine can be expensive.
Do not code in ugly uppercase. There is NO programming standard in use today that states that reserved words need to be coded in uppercase. Have a look at Java standards, .Net standards, Pascal standards, C/C++ standards.
The function should look as follows (assuming it is a wise decision to return a number when a boolean or Y/N flag value is expected) - as already shown previously in the thread:
SQL> create or replace function isLeapYear( d date ) return integer is
2 begin
3 return(
4 case
5 when ( mod(extract(year from d),4) = 0 and
6 mod(extract(year from d),100) != 0
7 )
8 or
9 mod(extract(year from d),400) = 0 then
10 1
11 else
12 0
13 end
14 );
15 end;
16 /
Function created.
SQL>
SQL> select isLeapYear(sysdate) as BIT from dual;
BIT
1
SQL> select isLeapYear(sysdate+300) as BIT from dual;
BIT
0
SQL> -
I am trying to call a function with LABVIEW developed in CCS compiler
I used MPLAB (CCS compiler) to develop c code that is used to transmit and receive messages to and from an automotive display. It works great as a stand alone. I would like to call this function from LABVIEW but am having difficulty doing so. Does anyone have experience calling a MPLAB developed project from LABVIEW? Thanks in advance.
MattPTE wrote:
I used MPLAB (CCS compiler) to develop c code that is used to transmit and receive messages to and from an automotive display. It works great as a stand alone. I would like to call this function from LABVIEW but am having difficulty doing so. Does anyone have experience calling a MPLAB developed project from LABVIEW? Thanks in advance.
Matt
MPLab is for programming PICs if I'm not mistaken. I'm not sure how you would want to call a function compiled in MPLab from LabVIEW directly. MPLab will create binary code for execution on PICs and there is no LabVIEW that could run on a PIC. On the other hand I didn't think you could create standard Windows DLLs, Mac shared libraries or similar in MPLab at all.
You will have to recompile your code in a C compiler that can create the standard shared library format for the plaform you want to call it from LabVIEW.
Rolf Kalbermatter
Rolf Kalbermatter
CIT Engineering Netherlands
a division of Test & Measurement Solutions -
Creating a function to return a table of records
Okay, I thought I knew how to do this but apparently not. I have a very complex query that connects multiple tables. I want to put the results of that query into a "table" (non-persistent) that can be passed to another procedure. So, I created an object/record that defines a single row in this table:
create or replace TYPE SHP_RECORD is OBJECT
(FIELD01 NUMBER(10),
FIELD02 NUMBER(10),
FIELD03 NUMBER(10),
FIELD04 NUMBER(10),
FIELD05 NUMBER(10),
FIELD06 VARCHAR2(200),
FILED07 NUMBER(10),
FIELD08 VARCHAR2(200),
FIELD09 NUMBER(10),
FIELD10 TIMESTAMP(6),
FIELD11 TIMESTAMP(6),
FIELD12 TIMESTAMP(6),
FIELD13 VARCHAR2(5),
FIELD14 NUMBER(10),
FIELD15 VARCHAR2(100),
FIELD16 VARCHAR2(4000),
FIELD17 VARCHAR2(1),
FIELD18 VARCHAR2(1));
Then I create another type that defines a table of SHP_RECORD:
Create or replace TYPE SHP_TABLE is TABLE of SHP_RECORD;
Now I have a function that puts the huge query into a text string (because it's got elements that change depending on what day of the week it's being run on so I have to keep it as a dynamic query. Now I want to run this query and put the results into a table. I've changed all the names to protect the innocent in this code snippet:
create or replace function get_SHP_data(p_cust_id IN NUMBER,
p_date IN TIMESTAMP) return SHP_TABLE as
begin
declare
shp_data_out SHP_TABLE;
TYPE shp_cur_type is REF CURSOR;
shp_cv shp_cur_type;
TYPE daily_query is VARRAY(7) of VARCHAR2(15);
query_values DAILY_QUERY;
day_index NUMBER;
old_program_id NUMBER;
chk_rundown NUMBER;
query_text VARCHAR2(3000);
row_index NUMBER;
program_freq_id NUMBER;
prog_seg_count NUMBER;
upload_seg_count NUMBER;
xfer_count NUMBER;
sched_count NUMBER;
bill_count NUMBER;
rcvr_text VARCHAR2(2000);
xmsn_start TIMESTAMP;
xmsn_end TIMESTAMP;
epi_status VARCHAR2(2000);
begin
query_values := daily_query('1, 3, 4, 12','1, 2, 5, 12','1, 2, 6, 12','1, 2, 7, 12','1, 2, 8, 12','1, 2, 9, 12','1, 3, 10, 12');
day_index := to_number(to_char(p_date,'D'));
query_text := {really ugly query here that includes concatinating a value from query_values as well as defines five bind variables numbered :1 through :5};
old_program_id := 0;
open shp_cv for query_text using p_date, p_date, p_date, p_date, p_cust_id;
fetch shp_cv bulk collect into shp_data_out;
close shp_cv;
end;
end;
Okay, the function compiles just fine. But when I try to run it I get:
select * from table(get_shp_data(226, SYSTIMESTAMP))
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected - got -
ORA-06512: at "SCHEMA.GET_SHP_DATA", line 69
The line it's blowing up on is "fetch ship_cv bulk collect into shp_data_out" I've checked and verified that the record/object structure SHP_RECORD matches in both type and order the values that are returned by the query. So...what gives? I've been beating my head against this particular problem for several days now and am no closer to a solution.
Any and all suggestions or corrections gratefully appreciated.
Oh, and this is being run in a 10g release 2 environment:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options
HELP??!!Hi,
Even though the fetch is seemingly taking the exact same types, Oracle will still need you to cast the resultset into the proper type.
Here's a short example of one way of doing it:
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.5.0
Connected as FSITJA
SQL>
SQL> create table my_table as select owner, table_name from all_tables where rownum <= 5;
Table created
SQL> create or replace type SHP_RECORD as object (owner varchar2(30), table_name varchar2(30));
2 /
Type created
SQL> create or replace type SHP_TABLE as table of SHP_RECORD;
2 /
Type created
SQL> create or replace function get_shp_data(p_owner in my_table.owner%type) return shp_table as
2 shp_data_out shp_table;
3 cur_shp sys_refcursor;
4 begin
5 open cur_shp for
6 select cast (multiset(select owner, table_name
7 from all_tables
8 where owner = p_owner
9 and rownum <= 5) as shp_table)
10 from dual;
11 fetch cur_shp
12 into shp_data_out;
13 return shp_data_out;
14 end;
15 /
Function created
SQL> select * from table(get_shp_data('SYS'));
OWNER TABLE_NAME
SYS TABLE_PRIVILEGE_MAP
SYS SYSTEM_PRIVILEGE_MAP
SYS STMT_AUDIT_OPTION_MAP
SYS P$POK_CFG
SYS DUALYou might want to check on Pipelined table functions and perhaps the function result cache in the docs, as means to improve your performance.
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17126/tuning.htm#LNPLS01210
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17126/subprograms.htm#LNPLS00817 -
Dynamic PL/SQL & substr, instr function
I am having trouble with incorporating the SUBSTR and INSTR functions into my dynamic PL/SQL procedure using Oracle 8i.
I have data that is packed into one column seperated by a delimiter (':')
I need to seperate the data to use indicidual pieces.
If I run my query in general -
select substr(secondcol, 1, instr(secondcol, ':',1,1)-1) ONE,
substr(secondcol,instr(secondcol, ':',1,1)+1,instr(secondcol, ':',1,1)-1) TWO,
substr(secondcol,instr(secondcol, ':',1,2)+1,instr(secondcol, ':',1,1)-1) THREE,
substr(secondcol,instr(secondcol, ':',1,3)+1,instr(secondcol, ':',1,1)-1) FOUR
from temp_table where firstcol=100
This works and gives me the right result.
e.g
DATA :
Firstcol SECONDCOL
100 1:2:3:4
Result:
ONE TWO THREE FOUR
1 2 3 4
However to make this generic if I use it in a function passing it a parameter which has ':' delimited data it does not work and gives me errors. All I want is to get the output as a string that looks like my query above so I can use it in my proc.
create or replace function MYJUNK(TFieldNew IN CHAR)
RETURN CHAR IS
UpdateString Varchar2(100);
BEGIN
UpdateString := 'First=substr('||TFieldNew||', 1, instr('||TFieldNew||', '':'',1,1)-1) ONE, ';
UpdateString := UpdateString || ' Second=substr('||TFieldNew||', instr('||TFieldNew||', '':'',1,2)+1, instr('||TFieldNew||', '':'',1,1)-1) TWO, ';
UpdateString := UpdateString || ' third=substr('||TFieldNew||', instr('||TFieldNew||', '':'',1,3)+1, instr('||TFieldNew||', '':'',1,1)-1) THREE from temp_table';
return UpdateString;
END;
The function compiles but gives me run time errors
This is what I get -
SQL> select myjunk('''1:2:3:4''') from dual;
select myjunk('''1:2:3:4''') from dual
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SGHDTA.MYJUNK", line 8
ORA-06512: at line 1You are getting an error because updatestring is longer than the 100 characters you defined it as. Try using VARCHAR2(4000). Also, if you are trying to generate the sql statement, you need to get rid of first=, second= and third= when you build the string.
This is what your function returns. I put in line breaks for clarity:
First=substr('1:2:3:4', 1, instr('1:2:3:4', ':',1,1)-1) ONE,
Second=substr('1:2:3:4', instr('1:2:3:4', ':',1,2)+1, instr('1:2:3:4',':',1,1)-1) TWO,
third=substr('1:2:3:4', instr('1:2:3:4', ':',1,3)+1,instr('1:2:3:4', ':',1,1)-1) THREE
from temp_tableIf you are trying to actually parse the column, then you need something more like:
create or replace procedure MYJUNK(TFieldNew IN VARCHAR2,out1 OUT VARCHAR2,
out2 OUT VARCHAR2, out3 OUT VARCHAR2) is
BEGIN
out1 := SUBSTR(TFieldNew,1, INSTR(TFieldNew,':',1,1)-1);
out2 := SUBSTR(TFieldNew, INSTR(TFieldNew,':',1,2)+1, INSTR(TFieldNew,':',1,1)-1);
out3 := SUBSTR(, INSTR(TFieldNew,':',1,3)+1, INSTR(TFieldNew,':',1,1)-1);
END; -
Display a register in a function
Hi,
I have a PL/SQL function compiled succesfully, but it doesn't works as I wish, and I don't know why. So I tried to display a register of a table but there are errors. Here is the code:
create or replace
PACKAGE BODY "SML_ACUMULADOS" as
-- Para que el usuario actualice los stocks erróneos de una clave desde Discoverer
FUNCTION actualizar_acumulados(p_counipro in VARCHAR2,
p_cjclmapr in VARCHAR2,
p_nuprovee in VARCHAR2,
p_caextrap in NUMBER,
p_caextran in NUMBER,
p_caexexpl in NUMBER,
p_caexalma in NUMBER)
RETURN NUMBER
IS
CURSOR c_acumulados is
SELECT counipro,
cjclmapr,
nuprovee,
caextrap,
caextran,
caexexpl,
caexalma
FROM sml_movimientos_2009
WHERE COUNIPRO = p_counipro
AND CJCLMAPR = p_cjclmapr
AND NUPROVEE = p_nuprovee;
--SET VERYFY OFF
SET SERVEROUTPUT ON SIZE 20000; --error
BEGIN
OPEN c_acumulados;
FOR i in c_acumulados LOOP
IF p_caexalma IS NOT NULL AND p_caexalma != i.caexalma THEN
UPDATE sml_movimientos_2009
SET CAEXALMA = p_caexalma
WHERE COUNIPRO = p_counipro
AND CJCLMAPR = p_cjclmapr
AND NUPROVEE = p_nuprovee;
DBMS_OUTPUT_LINE(i.caexalma); --Error
RETURN 1;
ELSE RETURN 0;
END IF;
END LOOP;
RETURN p_caexalma;
CLOSE c_acumulados;
END;
END;
The error I display is:
Error(29,21): PLS-00103: Encountered the symbol "ON" when expecting one of the following: := . ( @ % ; not null range default character The symbol "; was inserted before "ON" to continue.
How can I display the caexalma value?
Thanks.Although what you told me works, the problem it's not fixed. Because I'm trying to display the value inside the table, that is, i_caexalma, not the parameter I type in the function. That's why I typed in the code:
DBMS_OUTPUT_LINE(i.caexalma); --Error
The important code is:
IF p_caexalma IS NOT NULL AND p_caexalma != i.caexalma THEN
UPDATE sml_movimientos_2009
SET CAEXALMA = p_caexalma
WHERE COUNIPRO = p_counipro
AND CJCLMAPR = p_cjclmapr
AND NUPROVEE = p_nuprovee;
--DBMS_OUTPUT_LINE(i.caexalma);
RETURN c_acumulados.i_caexalma;
p_caexalma is the parameter of the function and it's possible to display it. But is it possible to display i.caexalma value? I want to check if this conditional is OK and the table sml_movimientos is updated. Now I know that this table is not updated and I want to know why.
Thanks. -
Function issue in oracle 8i (817)
Hello,
Following objects are created in database
1. CREATE OR REPLACE TYPE PARAMETER_OBJ AS OBJECT
RUN VARCHAR2(2000),
BATCH_NO VARCHAR2(2000),
DAY_NO VARCHAR2(2000),
PARAMETER_NAME VARCHAR2(2000),
PARAMETER_VALUE VARCHAR2(2000),
PARAMETER_UOM VARCHAR2(2000)
2. CREATE OR REPLACE TYPE PARAMETER_TYP AS TABLE OF PARAMETER_OBJ ;
Info abt the function
1. function return type is PARAMETER_TYP.
2. Inside the function i initialize tblParameters PARAMETER_TYP:=PARAMETER_TYP();
3. Create a temporary table[TMP_PARAMETER] .The structure of the table is same as "PARAMETER_OBJ"
4. In a loop Insert data into temporary table
5. At the end issue following select statement
SELECT CAST (MULTISET (SELECT * FROM TMP_PARAMETER)
AS PARAMETER_TYP )
INTO tblParameters FROM DUAL;
6. issue commit (which flushes temp table)
7. return RETURN tblParameters
Finally issue following sql statement to get data from the function
select * from table(T_Get_ParameterValue('A03052','-1-SPINNER-CELL_AGE-15L,3-SPINNER-DOUBLING_TIME-15L'))
It works oracle 10g. In oracle 817 function compiles.But if i select as shown above it gives erorr says nested table not found..
Can any body help me.1. CREATE OR REPLACE TYPE PARAMETER_OBJ AS OBJECT
RUN VARCHAR2(2000),
BATCH_NO VARCHAR2(2000),
DAY_NO VARCHAR2(2000),
PARAMETER_NAME VARCHAR2(2000),
PARAMETER_VALUE VARCHAR2(2000),
PARAMETER_UOM VARCHAR2(2000)
2. CREATE OR REPLACE TYPE PARAMETER_TYP AS TABLE OF PARAMETER_OBJ ;
# Code
CREATE OR REPLACE Function T_Get_ParameterValue
a_run CLOB,
a_dytblcoleqp CLOB
-- [T]: TO_REMOVE: Changed return type.
-- 1. Need to create a temporary table TMP_PARAMETER which has the same structure as your object.
--RETURN PARAMETER_TYP PIPELINED
RETURN PARAMETER_TYP
AS
PRAGMA AUTONOMOUS_TRANSACTION;
TYPE cursor_type IS REF CURSOR;
TYPE STR_LST IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
l_sql varchar2(4000);
l_cr cursor_type;
-- [T]: TO_REMOVE: Added variable.
tblParameters PARAMETER_TYP:=PARAMETER_TYP();
l_batch_lst STR_LST;
l_tblcl_lst STR_LST;
l_tbl_lst STR_LST;
l_col_lst STR_LST;
l_day_lst STR_LST;
l_sign_lst STR_LST;
l_eqp_lst STR_LST;
l_con CLOB;
l_tmp varchar2(4000);--Tmp store
l_pos number:=0; -- LOcator of the seperaotr
s_pos number:=0; -- start position
l_k number:=0; -- Array controller
l_n number:=0; -- Array controller
f_sp varchar2(1):=','; -- First seperator
s_sp varchar2(1):='-'; -- Second seperator
l_col_desc varchar2(2000);
l_column_type varchar2(2000);
l_capture_date varchar2(2000);
-- ipc list
l_parameter_uom varchar2(2000);
l_action_limit_max varchar2(2000);
l_action_limit_min varchar2(2000);
l_control_limit_max varchar2(2000);
l_control_limit_min varchar2(2000);
l_center_line varchar2(2000);
l_parameter_value varchar2(2000);
l_batch_id varchar2(2000);
l_batch_no varchar2(2000);
l_day_no varchar2(2000);
l_eqp varchar2(2000);
l_date date;
-- Loop Control
l_cont number;
i number;
--remove
l_sqlerm varchar2(2000);
BEGIN
l_pos:=0; -- LOcator of the seperaotr
-- Parsing
-- Parsing the tbl and col list
s_pos:=1;
l_cont:=1; -- loop control
i:=0; -- loop control
while (l_cont=1) loop
i:=i+1;
l_k:=l_k+1;
--determine position
l_pos:=instr(a_dytblcoleqp,f_sp,1,i);
if l_pos=0 and i=1 then -- no need to parse ,only 1 record
l_tmp:=a_dytblcoleqp;
l_tblcl_lst(l_k):=l_tmp;
--exit;
l_cont:=0;
elsif l_pos=0 and i!=1 then
l_tmp:=substr(a_dytblcoleqp,s_pos);
l_tblcl_lst(l_k):=l_tmp;
l_k:=l_k-1; re caluclate. nothing else to parse
--exit;
l_cont:=0;
else -- continue parse
l_tmp:=substr(a_dytblcoleqp,s_pos,l_pos-s_pos);
l_tblcl_lst(l_k):=l_tmp;
s_pos:=l_pos+1;
end if;
end loop; -- end of while loop
for j in 1..l_k loop
-- validate sign
if substr(l_tblcl_lst(j),1,1)='-' then
l_tblcl_lst(j):=substr(l_tblcl_lst(j),2);
l_sign_lst(j):='-';
else
l_sign_lst(j):='';
end if;
l_day_lst(j):=substr(l_tblcl_lst(j),1,instr(l_tblcl_lst(j),s_sp,1,1)-1);
l_day_lst(j):=l_sign_lst(j)||l_day_lst(j);
l_tbl_lst(j):=substr(l_tblcl_lst(j),instr(l_tblcl_lst(j),s_sp,1,1)+1,instr(l_tblcl_lst(j),s_sp,1,2)-instr(l_tblcl_lst(j),s_sp,1,1)-1);
l_col_lst(j):=substr(l_tblcl_lst(j),instr(l_tblcl_lst(j),s_sp,1,2)+1,instr(l_tblcl_lst(j),s_sp,1,3)-instr(l_tblcl_lst(j),s_sp,1,2)-1);
l_eqp_lst(j):=substr(l_tblcl_lst(j),(instr(l_tblcl_lst(j),s_sp,1,3)+1));
end loop;
-- Parsing Batch List
s_pos:=1;
l_cont:=1; -- loop control
i:=0; -- loop control
while (l_cont=1) loop
i:=i+1;
l_n:=l_n+1;
--determine position
l_pos:=instr(a_run,f_sp,1,i);
if l_pos=0 and i=1 then -- no need to parse ,only 1 record
l_tmp:=a_run;
l_batch_lst(l_n):=l_tmp;
l_cont:=0;--exit while loop
elsif l_pos=0 and i!=1 then
l_tmp:=substr(a_run,s_pos);
l_batch_lst(l_n):=l_tmp;
l_cont:=0;--exit while loop
else -- continue parse
l_tmp:=substr(a_run,s_pos,l_pos-s_pos);
l_batch_lst(l_n):=l_tmp;
s_pos:=l_pos+1;
end if;
end loop;
--- end of Parsing
-- Build con catenate list
for k in 1..l_n loop
--l_con:=NULL;
--l_con:='(';
--l_con:=l_con||''''||l_batch_lst(k)||''')';
--dbms_output.put_line(l_con);
for j in 1..l_k loop
-- 1 -- Get col desc
begin
select COLUMN_DESCR,COLUMN_TYPE,CAPTURE_DATE
into l_col_desc,l_column_type,l_capture_date
from MDM_ALL_PARAMETER_LIST
where table_name=upper(l_tbl_lst(j))
and column_name=upper(l_col_lst(j));
exception
when others then
l_col_desc:=NULL;
l_column_type:=NULL;
l_capture_date:=NULL;
end;
--dbms_output.put_line(l_batch_lst(k)||'-'||l_tbl_lst(j)||'-'||l_col_lst(j)||'-'||l_col_desc||'-'||to_char(l_capture_date));
--Build Sql Statement
if l_tbl_lst(j)='THAW' then
l_sql:=NULL;
l_sql:='select distinct spinner.BATCH_ID as batch_id,thaw.BIN_NO as bin_no,ipc.DAY_NO as day_no,NULL as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,thaw.'||l_col_lst(j)||','||l_capture_date;
l_sql:=l_sql||' from SPINNER spinner, BIN_HIER bin_hier, THAW thaw,IPC_LIMITS ipc';
l_sql:=l_sql||' where spinner.bin_no = bin_hier.bin_no';
l_sql:=l_sql||' and bin_hier.PROCESS_STEP =30';
l_sql:=l_sql||' and bin_hier.Revival_no = thaw.Revival_no';
l_sql:=l_sql||' and spinner.bin_no=ipc.LOT(+)';
l_sql:=l_sql||' and spinner.BATCH_ID=ipc.BATCH_ID(+)';
l_sql:=l_sql||' and spinner.BATCH_ID=:1';
l_sql:=l_sql||' and ipc.TABLE_NAME(+)=:2';
l_sql:=l_sql||' and ipc.COLUMN_NAME(+)=:3';
l_sql:=l_sql||' and ipc.SITE_ID(+)=:4';
--dbms_output.put_line(l_sql);
elsif l_tbl_lst(j)='THAW_SAMPLES' then
if l_col_lst(j)!='CALC' then
l_sql:=NULL;
l_sql:='select distinct spinner.BATCH_ID as batch_id,thaw_samples.BIN_NO as bin_no,thaw_samples.DAY_NO as day_no,NULL as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,thaw_samples.'||l_col_lst(j)||',thaw_samples.'||l_capture_date;
else
l_sql:=NULL;
--l_sql:='select spinner.BATCH_ID as batch_id,thaw_samples.BIN_NO as bin_no,thaw_samples.DAY_NO as day_no,NULL as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,null as Parameter_value,thaw_samples.'||l_capture_date;
l_sql:='select distinct spinner.BATCH_ID as batch_id,thaw_samples.BIN_NO as bin_no,thaw_samples.DAY_NO as day_no,NULL as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,Get_IPC_Parameter_Value('''||l_tbl_lst(j)||''''||','||''''||l_col_lst(j)||''',spinner.BATCH_ID,thaw_samples.BIN_NO,thaw_samples.DAY_NO),thaw_samples.'||l_capture_date;
end if;
l_sql:=l_sql||' from SPINNER spinner, BIN_HIER bin_hier, THAW thaw,THAW_SAMPLES thaw_samples,IPC_LIMITS ipc';
l_sql:=l_sql||' where spinner.bin_no = bin_hier.bin_no';
l_sql:=l_sql||' and bin_hier.PROCESS_STEP =30';
l_sql:=l_sql||' and bin_hier.Revival_no = thaw.Revival_no';
l_sql:=l_sql||' and thaw_samples.bin_no=thaw.bin_no';
l_sql:=l_sql||' and spinner.bin_no=ipc.LOT(+)';
l_sql:=l_sql||' and spinner.BATCH_ID=ipc.BATCH_ID(+)';
l_sql:=l_sql||' and spinner.BATCH_ID=:1';
l_sql:=l_sql||' and ipc.TABLE_NAME(+)=:2';
l_sql:=l_sql||' and ipc.COLUMN_NAME(+)=:3';
l_sql:=l_sql||' and ipc.SITE_ID(+)=:4';
l_sql:=l_sql||' and ipc.day_no(+)=:5';
l_sql:=l_sql||' and thaw_samples.day_no=:6';
elsif l_tbl_lst(j) in ('F1250L_TEST','F200L_TEST','F4000L_TEST','F8000L_TEST') then
l_sql:=NULL;
l_sql:='select t.batch_id,t.bin_no,t.DAY_NO as day_no,NULL as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,t.'|| l_col_lst(j)||',t.'||l_capture_date;
l_sql:=l_sql||' from '||l_tbl_lst(j)||' t,IPC_LIMITS ipc ';
l_sql:=l_sql||' where 1=1';
l_sql:=l_sql||' and t.BATCH_ID=ipc.BATCH_ID(+)';
l_sql:=l_sql||' and t.BIN_NO=ipc.LOT(+)';
l_sql:=l_sql||' and t.day_no=ipc.day_no(+)';
l_sql:=l_sql||' and t.batch_id=:1';
l_sql:=l_sql||' and ipc.TABLE_NAME(+)=:2';
l_sql:=l_sql||' and ipc.COLUMN_NAME(+)=:3';
l_sql:=l_sql||' and ipc.SITE_ID(+)=:4';
l_sql:=l_sql||' and t.day_no=:5';
elsif l_tbl_lst(j) in ('SPINNER_SAMPLES') then
l_sql:=NULL;
l_sql:='select smp.batch_id,smp.bin_no,smp.DAY_NO as day_no,spn.src_vessel_id as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,smp.'|| l_col_lst(j)||',smp.'||l_capture_date;
l_sql:=l_sql||' from SPINNER spn , SPINNER_SAMPLES smp,IPC_LIMITS ipc ';
l_sql:=l_sql||' where 1=1';
l_sql:=l_sql||' and spn.bin_no=smp.bin_no';
l_sql:=l_sql||' and smp.BATCH_ID=ipc.BATCH_ID(+)';
l_sql:=l_sql||' and smp.DAY_NO=ipc.DAY_NO(+)';
l_sql:=l_sql||' and smp.BIN_NO=ipc.LOT(+)';
l_sql:=l_sql||' and smp.batch_id=:1';
l_sql:=l_sql||' and ipc.TABLE_NAME(+)=:2';
l_sql:=l_sql||' and ipc.COLUMN_NAME(+)=:3';
l_sql:=l_sql||' and ipc.SITE_ID(+)=:4';
l_sql:=l_sql||' and smp.DAY_NO(+)=:5';
l_sql:=l_sql||' and upper(trim(replace(spn.src_vessel_id,'' '')))=:6';
elsif l_tbl_lst(j) in ('SPINNER') then
l_sql:=NULL;
l_sql:='select t.batch_id,t.bin_no,null as day_no,t.src_vessel_id as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,t.'|| l_col_lst(j)||',t.'||l_capture_date;
l_sql:=l_sql||' from '||l_tbl_lst(j)||' t,IPC_LIMITS ipc ';
l_sql:=l_sql||' where 1=1';
l_sql:=l_sql||' and t.BATCH_ID=ipc.BATCH_ID(+)';
l_sql:=l_sql||' and t.BIN_NO=ipc.LOT(+)';
l_sql:=l_sql||' and t.batch_id=:1';
l_sql:=l_sql||' and ipc.TABLE_NAME(+)=:2';
l_sql:=l_sql||' and ipc.COLUMN_NAME(+)=:3';
l_sql:=l_sql||' and ipc.SITE_ID(+)=:4';
l_sql:=l_sql||' and upper(trim(replace(t.src_vessel_id,'' '')))=:5';
else
-- rest
l_sql:=NULL;
l_sql:='select t.batch_id,t.bin_no,ipc.DAY_NO as day_no,NULL as eqp,ipc.PARAMETER_UOM as parameter_uom ,ipc.IPC_ACTION_LIMIT_MAX as ipc_action_limit_max,ipc.IPC_ACTION_LIMIT_MIN as ipc_action_limit_min,ipc.IPC_CONTROL_LIMIT_MAX as ipc_control_limit_max,ipc.IPC_CONTROL_LIMIT_MIN as ipc_control_limit_min,ipc.CENTER_LINE as center_line,t.'|| l_col_lst(j)||',t.'||l_capture_date;
l_sql:=l_sql||' from '||l_tbl_lst(j)||' t,IPC_LIMITS ipc ';
l_sql:=l_sql||' where 1=1';
l_sql:=l_sql||' and t.BATCH_ID=ipc.BATCH_ID(+)';
l_sql:=l_sql||' and t.BIN_NO=ipc.LOT(+)';
l_sql:=l_sql||' and t.batch_id=:1';
l_sql:=l_sql||' and ipc.TABLE_NAME(+)=:2';
l_sql:=l_sql||' and ipc.COLUMN_NAME(+)=:3';
l_sql:=l_sql||' and ipc.SITE_ID(+)=:4';
end if;
-- Open the cursor and filled up object
if l_tbl_lst(j)='THAW_SAMPLES' then
open l_cr for l_sql using l_batch_lst(k),l_tbl_lst(j),l_col_lst(j),1,l_day_lst(j),l_day_lst(j);
loop
null;
fetch l_cr into l_batch_id,l_batch_no,l_day_no,l_eqp,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_parameter_value,l_date;
exit when l_cr%notfound;
--PIPE ROW(PARAMETER_OBJ (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date) );
-- [T]: TO_REMOVE: Changed code to populate the temporary table.
INSERT INTO TMP_PARAMETER VALUES (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date);
end loop;
close l_cr;
elsif l_tbl_lst(j) in ('SPINNER_SAMPLES') then
open l_cr for l_sql using l_batch_lst(k),l_tbl_lst(j),l_col_lst(j),1,l_day_lst(j),l_eqp_lst(j);
loop
null;
fetch l_cr into l_batch_id,l_batch_no,l_day_no,l_eqp,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_parameter_value,l_date;
exit when l_cr%notfound;
--PIPE ROW(PARAMETER_OBJ (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date) );
-- [T]: TO_REMOVE: Changed code to populate the temporary table.
INSERT INTO TMP_PARAMETER VALUES (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date);
end loop;
close l_cr;
null;
elsif l_tbl_lst(j) in ('SPINNER') then
open l_cr for l_sql using l_batch_lst(k),l_tbl_lst(j),l_col_lst(j),1,l_eqp_lst(j);
loop
null;
fetch l_cr into l_batch_id,l_batch_no,l_day_no,l_eqp,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_parameter_value,l_date;
exit when l_cr%notfound;
-- PIPE ROW(PARAMETER_OBJ (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date) );
-- [T]: TO_REMOVE: Changed code to populate the temporary table.
INSERT INTO TMP_PARAMETER VALUES (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date);
end loop;
close l_cr;
elsif l_tbl_lst(j) in ('F1250L_TEST','F200L_TEST','F4000L_TEST','F8000L_TEST') then
null;
open l_cr for l_sql using l_batch_lst(k),l_tbl_lst(j),l_col_lst(j),1,l_day_lst(j);
loop
null;
fetch l_cr into l_batch_id,l_batch_no,l_day_no,l_eqp,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_parameter_value,l_date;
exit when l_cr%notfound;
-- PIPE ROW(PARAMETER_OBJ (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date) );
-- [T]: TO_REMOVE: Changed code to populate the temporary table.
INSERT INTO TMP_PARAMETER VALUES (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date);
end loop;
close l_cr;
else
open l_cr for l_sql using l_batch_lst(k),l_tbl_lst(j),l_col_lst(j),1;
loop
null;
fetch l_cr into l_batch_id,l_batch_no,l_day_no,l_eqp,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_parameter_value,l_date;
exit when l_cr%notfound;
-- PIPE ROW(PARAMETER_OBJ (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date) );
-- [T]: TO_REMOVE: Changed code to populate the temporary table.
INSERT INTO TMP_PARAMETER VALUES (l_batch_id,l_batch_no,l_day_no,l_col_desc,l_parameter_value,l_parameter_uom,l_action_limit_max,l_action_limit_min,l_control_limit_max,l_control_limit_min,l_center_line,l_eqp,'1',l_tbl_lst(j),l_col_lst(j),l_date);
end loop;
close l_cr;
null;
end if;
end loop;-- end of for loop for j in 1..l_k loop
end loop; --end of for j in 1..l_n loop
-- [T]: TO_REMOVE: Return the data from the temporary table into the table type.
-- Return data into table type.
SELECT CAST (MULTISET (SELECT * FROM TMP_PARAMETER)
AS PARAMETER_TYP )
INTO tblParameters FROM DUAL;
-- [T]: TO_REMOVE: Added commit so that the data in the temporary table is deleted.
COMMIT;
-- [T]: TO_REMOVE: Return the table type.
-- return ;
RETURN tblParameters;
EXCEPTION
WHEN OTHERS THEN
--l_sqlerm:=substr(sqlerrm,1,200);
ROLLBACK;
RAISE_APPLICATION_ERROR (-20001, SQLERRM);
return NULL;
END;
# Select sql statement
select *
from table(T_Get_ParameterValue('A03052','-1-SPINNER-CELL_AGE-15L,3-SPINNER-DOUBLING_TIME-15L')) -
Db function throws ORA-04067 Procedure does not exist error in forms
I have a db function that returns a value that I assign to a non-db item in Forms. The function compiles fine in the database, I've granted execute privileges to the forms user, and the form in which it's called compiles fine, but when I run the form and the trigger in which the function is called is fired, I get a ORA-04067 error, and Display_error doesn't show any additional information. My function syntax is as follows:
CREATE OR REPLACE FUNCTION f_method_in_prod(form_smi_field varchar2) RETURN VARCHAR2 IS
cur_smi varchar2(200) := form_smi_field;
cursor smi_lu is
select source_method_identifier from nemi_data.method
where cur_smi = source_method_identifier;
smi_var varchar2(200);
begin
open smi_lu;
fetch smi_lu into smi_var;
close smi_lu;
if smi_var is not null
then
RETURN 'yes';
end if;
END f_method_in_prod;
I've tried calling the function as function_name and as schema_name.function_name in the form and I get the error regardless of the format I use.
I'm using Forms 9.0.4
Any suggestions?
thanksI am not sure if this would cause the 04067 error, but your function does not return anything if smi_var is null. That is definitely a big problem.
Here is a function that should work better:
CREATE OR REPLACE FUNCTION f_method_in_prod(form_smi_field varchar2) RETURN VARCHAR2 IS
yes_no varchar2(3);
Begin
Begin
Select 'yes' into yes_no from dual where exists
(select null from nemi_data.method
where source_method_identifier = form_smi_field);
Exception when no_data_found then yes_no := 'no';
End;
Return yes_no;
END f_method_in_prod; -
PLS-00630: pipelined functions must have a supported collection return type
Hello, I created an TYPE of OBJECT and a PLSQL Function as shown below, but the function compilation errors with following. Not sure where is the issue?
PLS-00630: pipelined functions must have a supported collection return typeThis is on Oracle 10g r2
CREATE OR REPLACE TYPE cxs_plsql_profiler_object_type AS OBJECT (
cxs_object_name VARCHAR2 (128),
cxs_object_type VARCHAR2 (19),
cxs_object_status VARCHAR2 (7),
cxs_read_execution NUMBER,
cxs_buffer_gets NUMBER,
cxs_disk_reads NUMBER,
cxs_executions NUMBER,
cxs_sorts NUMBER,
cxs_sharable_mem NUMBER,
cxs_address NUMBER,
cxs_hashvalue NUMBER,
cxs_osuser VARCHAR2 (30),
cxs_username VARCHAR2 (30),
cxs_module VARCHAR2 (48),
cxs_machine VARCHAR2 (64),
cxs_status VARCHAR2 (8),
cxs_terminal VARCHAR2 (16),
cxs_percentconsume NUMBER,
cxs_percentrepeat NUMBER,
cxs_plan VARCHAR2 (120),
target_name VARCHAR2 (200),
referenced_name VARCHAR2 (200),
referenced_type VARCHAR2 (200),
targetowner VARCHAR2 (200),
refowner VARCHAR2 (200)
)and here is the API
FUNCTION CXS_GENERATE_PLSQL_PROFILER
RETURN cxs_plsql_profiler_object_type
PIPELINED IS
out_rec cxs_plsql_profiler_object_type ;
plsbatch plsql_batch;
skount integer;
dpendrec depend_tab;
dkount integer;
CURSOR objects
IS
SELECT object_name, object_type
FROM dba_objects
WHERE status = 'VALID'
AND owner NOT IN ('SYS', 'SYSTEM')
AND object_type IN ('PACKAGE', 'PROCEDURE', 'FUNCTION');
CURSOR apis (p_object dba_objects.object_name%TYPE)
IS
SELECT DISTINCT *
FROM (SELECT SUBSTR (a.sql_text, 1, 50) sql_text,
TRUNC
( a.disk_reads
/ DECODE (a.executions,
0, 1,
a.executions
) reads_per_execution,
a.buffer_gets, a.disk_reads, a.executions,
a.sorts, a.sharable_mem, a.address,
a.hash_value, b.osuser, b.username,
b.module, b.machine, b.status, b.terminal,
ROUND
(cxs_db_info.kompute_percentofsql
(a.sharable_mem),
5
) percentkonsume,
cxs_db_info.kount_repeat
(b.osuser,
b.terminal
) percentr,
c.operation explainplan
FROM v$sqlarea a, v$session b, v$sql_plan c
WHERE b.sql_hash_value = a.hash_value
AND b.sql_address = a.address
AND a.hash_value = c.hash_value
AND a.address = c.address
AND b.status = 'ACTIVE'
AND UPPER (a.sql_text) LIKE
'%' || p_object || '%'
AND c.ID = 0
ORDER BY 2 DESC)
WHERE ROWNUM <= 50; --profile option
BEGIN
skount := 0;
dkount := 0;
FOR i IN objects
LOOP
FOR j IN apis (i.object_name)
LOOP
skount := skount + 1;
plsbatch(skount).cxs_object_name := i.object_name;
plsbatch(skount).cxs_object_type := i.object_type;
plsbatch(skount).cxs_object_status := i.object_status;
plsbatch(skount).cxs_read_execution := j.reads_per_execution;
plsbatch(skount).cxs_buffer_gets := j.buffer_gets;
plsbatch(skount).cxs_disk_reads := j.disk_reads;
plsbatch(skount).cxs_executions := j.executions;
plsbatch(skount).cxs_sorts := j.sorts;
plsbatch(skount).cxs_sharable_mem := j.sharable_mem;
plsbatch(skount).cxs_address := j.address;
plsbatch(skount).cxs_hashvalue := j.hashvalue;
plsbatch(skount).cxs_osuser := j.osuser;
plsbatch(skount).cxs_username := j.username;
plsbatch(skount).cxs_module := j.module;
plsbatch(skount).cxs_machine := j.machine;
plsbatch(skount).cxs_status := j.status;
plsbatch(skount).cxs_terminal := j.terminal;
plsbatch(skount).cxs_percentconsume := j.percentconsume;
plsbatch(skount).cxs_percentrepeat := j.percentrepeat;
plsbatch(skount).cxs_plan := j.explainplan;
END LOOP;
FOR dd IN dpend (i.object_name)
LOOP
dkount := dkount + 1;
dependrec (dkount).target_name := dd.NAME;
dependrec (dkount).refname := dd.referenced_name;
dependrec (dkount).reftype := dd.referenced_type;
dependrec (dkount).target_owner := dd.owner;
dependrec (dkount).refowner := dd.referenced_owner;
END LOOP;
END LOOP;
for a in 1..skount loop
out_rec.cxs_object_type := plsbatch(a).object_type;
out_rec.cxs_object_status := plsbatch(a).object_status;
out_rec.cxs_read_execution := plsbatch(a).reads_per_execution;
out_rec.cxs_buffer_gets := plsbatch(a).buffer_gets;
out_rec.cxs_disk_reads := plsbatch(a).disk_reads;
out_rec.cxs_executions := plsbatch(a).executions;
out_rec.cxs_sorts := plsbatch(a).sorts;
out_rec.cxs_sharable_mem := plsbatch(a).sharable_mem;
out_rec.cxs_address := plsbatch(a).address;
out_rec.cxs_hashvalue := plsbatch(a).hashvalue;
out_rec.cxs_osuser := plsbatch(a).osuser;
out_rec.cxs_username := plsbatch(a).username;
out_rec.cxs_module := plsbatch(a).module;
out_rec.cxs_machine := plsbatch(a).machine;
out_rec.cxs_status := plsbatch(a).status;
out_rec.cxs_terminal := plsbatch(a).terminal;
out_rec.cxs_percentconsume := plsbatch(a).percentconsume;
out_rec.cxs_percentrepeat := plsbatch(a).percentrepeat;
out_rec.cxs_plan := plsbatch(a).explainplan;
PIPE ROW(out_rec);
end loop;
for b in 1..dkount loop
out_rec.target_name := dd.NAME;
out_rec.refname := dependrec (b).referenced_name;
out_rec.reftype := dependrec (b).referenced_type;
out_rec.target_owner := dependrec (b).owner;
out_rec.refowner := dependrec (b).referenced_owner;
PIPE ROW(out_rec);
end loop;
RETURN;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.format_error_backtrace);
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END; and below are tradtional table types that are used in code above.
TYPE type_plsql_rec IS RECORD (
cxs_object_name VARCHAR2 (128),
cxs_object_type VARCHAR2 (19),
cxs_object_status VARCHAR2 (7),
cxs_read_execution NUMBER,
cxs_buffer_gets NUMBER,
cxs_disk_reads NUMBER,
cxs_executions NUMBER,
cxs_sorts NUMBER,
cxs_sharable_mem NUMBER,
cxs_address NUMBER,
cxs_hashvalue NUMBER,
cxs_osuser VARCHAR2 (30),
cxs_username VARCHAR2 (30),
cxs_module VARCHAR2 (48),
cxs_machine VARCHAR2 (64),
cxs_status VARCHAR2 (8),
cxs_terminal VARCHAR2 (16),
cxs_percentconsume NUMBER,
cxs_percentrepeat NUMBER,
cxs_plan VARCHAR2 (120)
TYPE plsql_batch IS TABLE OF type_plsql_rec
INDEX BY BINARY_INTEGER;
TYPE type_depend_tab IS RECORD (
target_name dba_dependencies.NAME%TYPE,
refname dba_dependencies.referenced_name%TYPE,
reftype dba_dependencies.referenced_type%TYPE,
target_owner dba_dependencies.owner%TYPE,
refowner dba_dependencies.referenced_owner%TYPE
TYPE depend_tab IS TABLE OF type_depend_tab
INDEX BY BINARY_INTEGER;
Thank you for your time in reading this post
RThank you Billy and Saubhik,
I have followed your guidelines and was able to resolve this error. Now, after successfully compiling the code, I attempted to execute it in a following way.
SELECT * FROM TABLE (cxs_generate_plsql_profiler);It gives following error: ORA-00904: "CXS_GENERATE_PLSQL_PROFILER": invalid identifier
I also tried putting in quotes like below
SELECT * FROM TABLE ('cxs_generate_plsql_profiler');Then, it gives following error:
ORA-22905: cannot access rows from a non-nested table item
Any Idea where I am doing wrong?
Thanks,
R -
Function to find Average salary
Hello everyone,
First of all I would like to say that I am a newbie to PL/SQL so please be patient with me. I am trying to create a function that will calculate the average salary for employees and compare the average salary to each employee's salary. If the employee's salary is lower than the average salary, my function will return true, elese it will return false.
I think I have a great start but need some guidance on what to do next. Here's my function so far:
CREATE OR REPLACE FUNCTION check_employee_salary
(p_empno IN NUMBER)
RETURN NUMBER
IS
lv_sal emp.sal%TYPE;
BEGIN
SELECT avg(sal)
INTO lv_sal
FROM emp
WHERE empno = p_empno;
RETURN (lv_sal);
END;
My function compiles but I can't figure out how to compare the avg(sal) to sal so that I can return true and false. Any guidance will be appreciated as I really want to understand PL/SQL and am trying very hard.
ThanksYour function currently returns the average salary for a single employee, and since (in scott.emp at least) an employee only has one salary, it will return that.
SQL> select empno, ename, job, sal, check_employee_salary(empno) from emp;
EMPNO ENAME JOB SAL CHECK_EMPLOYEE_SALARY(EMPNO)
7369 SMITH CLERK 800 800
7499 ALLEN SALESMAN 1600 1600
7521 WARD SALESMAN 1250 1250
7566 JONES MANAGER 2975 2975
7654 MARTIN SALESMAN 1250 1250
7698 BLAKE MANAGER 2850 2850
7782 CLARK MANAGER 2450 2450
7788 SCOTT ANALYST 3000 3000
7839 KING PRESIDENT 5000 5000
7844 TURNER SALESMAN 1500 1500
7876 ADAMS CLERK 1100 1100
7900 JAMES CLERK 950 950
7902 FORD ANALYST 3000 3000
7934 MILLER CLERK 1300 1300
14 rows selected.To report whether a specified employee's salary was above or below average, it would have to find the overall average (select avg(sal) from emp) and compare that to the specified employee's salary (select sal from emp where empno = p_empno). This would however be about the most inefficient way imaginable to derive this rather odd statistic. The easy way is using straight SQL:
select empno, ename, job, sal
, avg(sal) over() as company_avg_sal
, case when sal < avg(sal) over() then 'Below'
when sal = avg(sal) over() then 'Average'
when sal > avg(sal) over() then 'Above'
end as comparison
from emp;
EMPNO ENAME JOB SAL COMPANY_AVG_SAL COMPARISON
7369 SMITH CLERK 800 2073.21429 Below
7499 ALLEN SALESMAN 1600 2073.21429 Below
7521 WARD SALESMAN 1250 2073.21429 Below
7566 JONES MANAGER 2975 2073.21429 Above
7654 MARTIN SALESMAN 1250 2073.21429 Below
7698 BLAKE MANAGER 2850 2073.21429 Above
7782 CLARK MANAGER 2450 2073.21429 Above
7788 SCOTT ANALYST 3000 2073.21429 Above
7839 KING PRESIDENT 5000 2073.21429 Above
7844 TURNER SALESMAN 1500 2073.21429 Below
7876 ADAMS CLERK 1100 2073.21429 Below
7900 JAMES CLERK 950 2073.21429 Below
7902 FORD ANALYST 3000 2073.21429 Above
7934 MILLER CLERK 1300 2073.21429 Below
14 rows selected. -
PL/SQL Using SQL%NOTFOUND to raise a user defined exception in a function
I have written the following function for finding the number of items in stock in the item table.
CREATE OR REPLACE function getAmount (ItemID IN NUMBER)
RETURN NUMBER
AS
invalid_id EXCEPTION;
returnedQty number;
BEGIN
Select qty
Into returnedQty
From item
Where itemNo = ItemID;
RETURN (returnedQty);
IF SQL%NOTFOUND THEN
RAISE invalid_id;
END IF;
COMMIT;
Exception
WHEN invalid_id THEN
DBMS_OUTPUT.PUT_LINE('Invalid ID entered');
END getAmount;
The function compiles successfully, although there is a problem that Oracle is not handling my user-defined exception invalid_id
If I use the following for a valid itemID:
DECLARE
return_value number;
BEGIN
return_value := getAmount(1);
DBMS_OUTPUT.PUT_LINE (return_value);
END;
then the function returns the quantity of items in stock correctly.
However, if I enter an incorrect itemID, say 20
DECLARE
return_value number;
BEGIN
return_value := getAmount(20);
DBMS_OUTPUT.PUT_LINE (return_value);
END;
The invalid_id exception is not raised, and the Oracle errors says: no_data_found and the function has not returned a value. If I add a no_data_found exception, this works perfectly, but for this assignment I must write my own user-defined error.
Any help would be very much appreciated!
Thank you.What you're trying to do, is to use an implicit cursor. Implicit cursors will raise no_data_found and too_many_rows in case of an error. Explicit cursors will not.
Also, you have a small coding error ... a little rewrite and your code will do as you want to:
CREATE OR REPLACE function getAmount (ItemID IN NUMBER)
RETURN NUMBER
AS
invalid_id EXCEPTION;
returnedQty number;
cursor citem is
Select qty
From item
Where itemNo = ItemID;
fnd boolean;
BEGIN
open citem;
fetch citem Into returnedQty;
fnd := citem%found;
close citem;
if fnd then
RETURN (returnedQty);
else
RAISE invalid_id;
END IF;
/* Do not catch your own exception or the calling code will not receive it.
Exception
WHEN invalid_id THEN
DBMS_OUTPUT.PUT_LINE('Invalid ID entered');
END getAmount;
Your problem is, you're not using a package. This means, that the calling code has no way of catching this user-defined exeption. The correct way is to define a package, define the userdefined exception in the package and refer to it in your code:
create or replace package amt
is
invalid_id EXCEPTION;
function getAmount (ItemID IN NUMBER)
RETURN NUMBER;
end;
create or replace package body amt
is
function getAmount (ItemID IN NUMBER)
RETURN NUMBER
AS
returnedQty number;
cursor citem is
Select qty
From item
Where itemNo = ItemID;
fnd boolean;
BEGIN
open citem;
fetch citem Into returnedQty;
fnd := citem%found;
close citem;
if fnd then
RETURN (returnedQty);
else
RAISE invalid_id;
END IF;
end;
end; -- end package
To do a simple test, you'll do:
declare
a number;
begin
a := amt.getAmount(123);
dbms_output.put_line('The result is '||a);
exception
when amt.invalid_id then
dbms_output.put_line('ID not found');
end;
Other ways is to raise the exception in your no_data_found block.
But I'm REALLY puzzled if there's really someone out there who prefers a user-defined exception instead of the clearly defined NO_DATA_FOUND exception.
I can't be sure of course, but are you sure what they mean is they don't want ANY exception? That's a pretty common requirement.
In general - explicit cursors are a bit faster because Oracle does not have to do a second fetch to determine TOO_MANY_ROWS. And it's not too much additional writing. Explicit cursors will never raise exceptions - unless you use dynamic sql and your SQL is invalid.
Good luck
Maybe you are looking for
-
Email PDF along with upload of files
I have a PDF form that the user will complete. On that form I have a submit button that submits the data to a JSP page that creates the PDF data into a FDF file on the server. I can create an email and attach that file and send it with no problem. My
-
Identifying A File Missing From A Playlist In The Master Library
I organize/store all my song files from the master library (about 2,100 files at this point) into playlists. Through some cross-referencing I have realized there is one song file in my master library that's not in a playlist (UUUGH!!!) This situation
-
same as headline
-
Got a new RAZR - major network issues in Glendale/Phoenix...
I'm in Glendale, AZ, a suburb of Phoenix, AZ. I just bought my Droid RAZR Friday. The store I bought my phone at had 2 bars on RAZRs, and 1 on the new Galaxy. They are located at 59th avenue & Northern in Glendale. In most of the areas I have been,
-
Translation error at update process (German)
Hi, during the update progress of Flash Player in German (on Windows 7), the text is translated wrong. Instead of "Installation wird zurzeit ausführt" it should be "Installation wird zurzeit ausgeführt". Kind regards Domar