Use function which returns clob in proceudre
Hello,
I need some help with a function call i am using.
I have a SYSMAN function which i like to call in procedure.
The output from the function is a CLOB.
Executing the statement in SqlPlus returns 2 lines of data, but written into a procedure returns in an error.
The procedure looks like this:
CREATE OR REPLACE PROCEDURE large_val as
cSql_text CLOB;
sSql_stmt varchar2(200);
job_id varchar2(80);
exec_id varchar2(80);
parm varchar2(50);
begin
job_id := '82A11DD897876D29E0400A0A8A1051A7';
exec_id := '0000000000000000';
parm := 'large_sql_script';
sSql_stmt := 'SELECT SYSMAN.MGMT_JOBS.get_large_param(' || ''''||job_id||'''' ||',' ||''''||exec_id||''''||','||''''||parm|| '''' || ') FROM DUAL;';
dbms_output.put_line(sSql_stmt);
execute immediate sSql_stmt into cSql_text;
END large_val;
The output from dbms_output i am able to run a statement in SqlPlus without error:
SELECT SYSMAN.MGMT_JOBS.get_large_param('82A11DD897876D29E0400A0A8A1051A7','0000000000000000','large_sql_script') FROM DUAL ;
and it returns 2 lines.
Running it as a procecure show's an error i don't understand.
exec large_val;
BEGIN large_val; END;
ERROR at line 1:
ORA-00911: invalid character
ORA-06512: at "SCHEMTS.LARGE_VAL", line 23
ORA-06512: at line 1
Hope anyone can help me.
Any help is appreciated.
Regards,
Ben
Kiran wrote:
you cannot use CLob with select query.Yes you can. At least since 10gR1, but possibly in earlier versions too.
@OP:
Why aren't you using bind variables? And why are you using dynamic sql at all?
You could just do
cSql_text := SYSMAN.MGMT_JOBS.get_large_param(job_id, exec_id, parm);
Similar Messages
-
Function which returns multiple values that can then be used in an SQL Sele
I'd like to create a function which returns multiple values that can then be used in an SQL Select statement's IN( ) clause
Currently, the select statement is like (well, this is a very simplified version):
select application, clientid
from tbl_apps, tbl_status
where tbl_apps.statusid = tbl_status.statusid
and tbl_status.approved > 0;
I'd like to pull the checking of the tbl_status into a PL/SQL function so my select would look something like :
select application, clientid
from tbl_apps
where tbl_apps.statusid in (myfunction);
So my function would be running this sql:
select statusid from tbl_status where approved > 0;
... will return values 1, 5, 15, 32 (and more)
... but I haven't been able to figure out how to return the results so they can be used in SQL.
Thanks for any help you can give me!!
Trisha GorrPerhaps take a look at pipelined functions:
Single column example:
SQL> CREATE OR REPLACE TYPE split_tbl IS TABLE OF VARCHAR2(32767);
2 /
Type created.
SQL> CREATE OR REPLACE FUNCTION split (p_list VARCHAR2, p_delim VARCHAR2:=' ') RETURN SPLIT_TBL PIPELINED IS
2 l_idx PLS_INTEGER;
3 l_list VARCHAR2(32767) := p_list;
4 l_value VARCHAR2(32767);
5 BEGIN
6 LOOP
7 l_idx := INSTR(l_list, p_delim);
8 IF l_idx > 0 THEN
9 PIPE ROW(SUBSTR(l_list, 1, l_idx-1));
10 l_list := SUBSTR(l_list, l_idx+LENGTH(p_delim));
11 ELSE
12 PIPE ROW(l_list);
13 EXIT;
14 END IF;
15 END LOOP;
16 RETURN;
17 END SPLIT;
18 /
Function created.
SQL> SELECT column_value
2 FROM TABLE(split('FRED,JIM,BOB,TED,MARK',','));
COLUMN_VALUE
FRED
JIM
BOB
TED
MARK
SQL> create table mytable (val VARCHAR2(20));
Table created.
SQL> insert into mytable
2 select column_value
3 from TABLE(split('FRED,JIM,BOB,TED,MARK',','));
5 rows created.
SQL> select * from mytable;
VAL
FRED
JIM
BOB
TED
MARK
SQL>Multiple column example:
SQL> CREATE OR REPLACE TYPE myrec AS OBJECT
2 ( col1 VARCHAR2(10),
3 col2 VARCHAR2(10)
4 )
5 /
Type created.
SQL>
SQL> CREATE OR REPLACE TYPE myrectable AS TABLE OF myrec
2 /
Type created.
SQL>
SQL> CREATE OR REPLACE FUNCTION pipedata(p_str IN VARCHAR2) RETURN myrectable PIPELINED IS
2 v_str VARCHAR2(4000) := REPLACE(REPLACE(p_str, '('),')');
3 v_obj myrec := myrec(NULL,NULL);
4 BEGIN
5 LOOP
6 EXIT WHEN v_str IS NULL;
7 v_obj.col1 := SUBSTR(v_str,1,INSTR(v_str,',')-1);
8 v_str := SUBSTR(v_str,INSTR(v_str,',')+1);
9 IF INSTR(v_str,',')>0 THEN
10 v_obj.col2 := SUBSTR(v_str,1,INSTR(v_str,',')-1);
11 v_str := SUBSTR(v_str,INSTR(v_str,',')+1);
12 ELSE
13 v_obj.col2 := v_str;
14 v_str := NULL;
15 END IF;
16 PIPE ROW (v_obj);
17 END LOOP;
18 RETURN;
19 END;
20 /
Function created.
SQL>
SQL> create table mytab (col1 varchar2(10), col2 varchar2(10));
Table created.
SQL>
SQL> insert into mytab (col1, col2) select col1, col2 from table(pipedata('(1,2),(2,3),(4,5)'));
3 rows created.
SQL>
SQL> select * from mytab;
COL1 COL2
1 2
2 3
4 5 -
Plsql use a function which returns a ref cursor
Hi
I've been using an function which returns a ref cursor. I've been returning this into a java resultset. Fine!
Now i'm in plsql and want to use the same function. I'm not sure how to get this resultset in plsql.It's not very practical to use a refcursor like you want to, but here you go
create or replace function test_ref
return sys_refcursor
is
v_rc sys_refcursor;
begin
open v_rc for select emp_name from emp ;
return v_rc;
end;
declare
v_rc sys_refcursor;
v_emp_name emp.emp_name%type;
begin
v_rc := test_ref ;
loop
fetch v_rc into v_emp_name ;
exit when v_rc%notfound ;
dbms_output.put_line('Employee Name: '||v_emp_name );
end loop;
end; -
Error while calling the function which returns SQL Query!!!
Hi,
I have a Function which returns SQL query. I am calling this function in my APEX report region source.
The query is dynamic SQL and its size varies based on the dynamic "where clause" condition.
But I am not able to execute this function.It gives me the following error in APEX region source.
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Even in SQL* Plus or SQL developer also same error .
The length of my query is more than 4000. I tried changing the variable size which holds my query in the function.
Earlier it was
l_query varchar2(4000)
Now I changed to
l_query varchar2(32767).
Still it is throwing the same error.
Can anybody help me to resolve this.???
Thanks
AlakaHi Varad,
I am already using 32k of varchar2. Then also it is not working.
It is giving the same error. I think there is something to do with buffer size.
My query size is not more than 4200. Even if i give 32k of varchar2 also buffer is able to hold only 3997 size of the query only.
Error is
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Tried CLOB also. It is not working.
Any other solution for this.
Thanks
Alaka -
Querying PL/SQL function which returns SYS_REFCURSOR
Hello:
I have a PL/SQL function with return type of SYS_REFCURSOR.
In SQLPlus, I can query it either as
var c refcursor
exec :c := func(...)
print c
or
select func(...) from dual;
Running the latter in Eclipse 3.3 with oracle DTP extensions installed gives me OracleResultSetImpl object in the SQL Results view.
Can the code be a little smarter and recognize that a sql query may return "indirect" resultset?
Regards,
ErnestThis is noted; will be the interface better to handle the return values. Thanks
-
Unit test, how to test a function which returns a PL/SQL table.
I've got the following type definition:
create or replace type method_tbl as table of varchar2(255);
/I've got the following function
function abc(p_param1 in varchar2) return method_tbl;When I create a unit test for this I am not able to specify what the table should contain on return of the function, all I can see is an empty table. Which is off course one of the unit tests. But I also want to test where the table that is returned contains a number of rows.
Is there something that I'm missing?
Typically the function is called like this:
select * from table(abc('a'));Thanks,
Ronald>
When I create a unit test for this I am not able to specify what the table should contain on return of the function, all I can see is an empty table. Which is off course one of the unit tests. But I also want to test where the table that is returned contains a number of rows.
Is there something that I'm missing?
>
You will have to create a collection that represents the result set and then compare that to the actual result set.
Assuming tables A and B you would typically have to do
1. SELECT * FROM A MINUS SELECT * FROM B -- what is in A that is NOT in B
2. SELECT * FROM B MINUS SELECT * FROM A -- what is in B that is NOT in A
You could combine those two queries into one with a UNION ALL but since the results are tables and the comparison is more complex it is common to write a function to determine the comparison result.
Here is sample code that shows how to create an expected result collection.
DECLARE
expectedItemList sys.OdciVarchar2List;
functionItemList sys.OdciVarchar2List;
newItemList sys.OdciVarchar2List;
expectedCount INTEGER;
countFunctionItemList INTEGER;
BEGIN
expectedItemList := sys.OdciVarchar2List('car','apple','orange','banana','kiwi');
expectedCount := 5; -- or query to count them
functionItemList := sys.OdciVarchar2List('car','apple','orange','peanut');
-- use your function to get the records
-- select * from myFunctino BULK COLLECT INTO functionItemList
IF functionItemList.count != expectedCount THEN
DBMS_OUTPUT.PUT_LINE('Count is ' || functionItemList.count || ' but should be ' || expectedCount);
END IF;
END;
Count is 4 but should be 5If the collections are the same type you can use the MULTISET operators.
See Solomon's reply in this thread for how to use the MULTISET operators on collections.
PLS-00306: wrong number or type of argument in call to 'MULTISET_UNION_ALL'
See MultisetOperators in the SQL Reference doc
http://docs.oracle.com/cd/B13789_01/server.101/b10759/operators006.htm
>
Multiset operators combine the results of two nested tables into a single nested table. -
How to call Java function which returns byteArray
context I have a class say
public class ByteArray{
public byte[] getByteArray(String str){
return str.getBytes();
}Consider i have object of ByteArray (some how) in native C code. I want to call getByteArray("Test") and obtain a byteArray. what is the C JNI function can i use?hy
CREATE OR REPLACE FUNCTION GET_SAL1(NN in NUMBER)
RETURN BOOLEAN
IS
BEGIN
INSERT INTO STD(ENO) VALUES(NN);
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
RETURN false;
END;
you can call :
if GET_SAL1(NN) then
else
error
end if;
I hope i understand
Regards -
How to call function which return and out
My function specifcation is
FUNCTION GetGoogleScholarActivation (
pi_clnt_id IN google_scholar_status.clnt_id%TYPE,
pi_status_type IN ci_status_type_tab_type,
po_status OUT ci_status_tab_type,
po_date OUT ci_date_tab_type
RETURN NUMBER ;
where type is
TYPE ci_status_type_tab_type IS TABLE OF VARCHAR2 (1) INDEX BY BINARY_INTEGER;
TYPE ci_status_tab_type IS TABLE OF VARCHAR2 (10) INDEX BY BINARY_INTEGER;
TYPE ci_date_tab_type IS TABLE OF VARCHAR2 (8) INDEX BY BINARY_INTEGER;
I am trying to call function in SQL PLUS for testing as
declare
var number ( 10);
TYPE p_st1 IS TABLE OF VARCHAR2 (1) INDEX BY BINARY_INTEGER;
p_st p_st1 ;
type p_status1 IS TABLE OF VARCHAR2 (1) INDEX BY BINARY_INTEGER;
p_status p_status1 ;
TYPE p_date1 IS TABLE OF VARCHAR2 (8) INDEX BY BINARY_INTEGER;
p_date p_date1 ;
Begin
p_st(0) := 'A';
var := PQDKGOSH.GetGoogleScholarActivation(11920 , p_st, p_status ,p_date );
dbms_output.put_line ('Activation_status '|| p_status(0) );
dbms_output.put_line ('Activation_date '|| p_date(0) );
dbms_output.put_line ('Retun Value'|| var );
End;
but getting error PLS-00306: wrong number or types of arguments in call to
'GETGOOGLESCHOLARACTIVATION'
so how to test from SQL PlusHI
I tried to execute below like this
declare
var number ( 10);
p_st ci_status_type_tab_type ;
p_status ci_status_tab_type;
p_date ci_date_tab_type;
Begin
p_st(0) := 'A';
var := PQDKGOSH.GetGoogleScholarActivation(11920 , p_st, p_status ,p_date );
dbms_output.put_line ('Activation_status '|| p_status(0) );
dbms_output.put_line ('Activation_date '|| p_date(0) );
dbms_output.put_line ('Retun Value'|| var );
End;
still iget error
PLS-00201: identifier 'CI_STATUS_TYPE_TAB_TYPE' must be declared
becuse this declareation i did in package specification .
and i am trying to execute the function . -
Create one function which return boolean
I want to write one function means if the resource status is cv locked in any one of the project,then automatically the status of this resource changed to unavailble for other projects.
Indicate that we can nominate the same resource for different projects but after cv lock that resources made unavailbale for other projects.
Require coding
Edited by: user12877889 on Jun 28, 2010 5:12 AMHi,
Well how to say, i suggest you to start with theses documentations:
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/toc.htm
http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/toc.htm
Thenyou'll probably have a better idea of what's an Oracle DB. After that comme back and describe the tools you're using and what's your requirements (what's you want to do, for what purpose...) then may be we'll be able to help you .. -
How to return multiples values useing functions
Hi to all,
I am using functions to return multiple values of two rows or multiple rows.
For example emp id = 100 and i need to return the value for this(empid) input and output of this first_name and salary.
I am tried in this way below but got errors (ORA-00932: inconsistent datatypes: expected NUMBER got HR.EMP_TYPE)
create or replace type emp_type as object(first_name varchar2(20),salary number);
create or replace function f1(empid in number)
return emp_type
as
emp_record emp_type;
begin
select first_name,salary into emp_record.first_name,emp_record.salary from employees where employee_id = empid ;
return emp_record;
end;
select f1(100) from dual;Sql is Sql and plsql is plsql. Though we can almost use all the sql objects inside a plsql code but vice versa is not always possible. Since plsql is tightly integrated with sql , if you return a number/date/varchar2 datatype values from plsql code to sql code,there is nothing wrong .Sql acknowledges this return type and knows well about how to handle it .But plsql record is a plsql specific datatype ,oracle was not built keeping in mind the fact that people will be creating difference types of records in plsql .So if you return a plsql datatype into a sql statement (which is processed by a sql engine) ,you need to tell oracle that I have written a plsql code which is going to return a record type so that sql engine can interpret it well.
So all you need to do is create record in sql (known as object in sql ),when you make one, the entry is going to be shown in user_types views. Now use it like any other data type. I assume that the forum link provided in the above post is the best one to understand.
Thanks,
Rahul -
Web Service function to return OracleDataReader
My current .Net code with ODP calls a data access layer function which returns an "OracleDataReader". We would like to test an alternate approach and call a web service function instead. When I try and create the Web Service function it does not allow me to specify "OracleDataReader" as the return since it gives an error that the function cannot be serialized since it "does not implement Add(System.Object).".
Is there an Oracle.DataAccess.Client alternative? Does this mean I have to return a "DataSet" since it is the only data structure which can be serialized?this is pseudo c#
snippets of a class definition NB Note the Serializable decoration
#region ADPerson definiton
[Serializable]
public class ADPerson
#region ADPerson fields
private string _postCode;
private string _deliveryOffice;
private string _telephoneNumber;
#region ADPeople collection of ADPerson
[Serializable]
public class ADPeople : System.Collections.CollectionBase
public int Add(ADPerson value)
This is in my web method
using AD = ADClasses;
#region main lookup method
[WebMethod(Description = "Lookup in Active Directory")]
public AD.ADPeople ADLookup(string strSearchCriteria, string strUser, string strPassword, string strDomain)
AD.ADPeople adPeople = new AD.ADPeople();
AD.ADPerson ap = new AD.ADPerson();
adPeople.Add(ap);
return adPeople;
Just make sure that your class(es) are serializable and return them from your web service. If you call the ser vice from a browser you will see your class as xml. If you call it from an app you can do something like
class c= callWebService(param);
HTH -
View or function to return the full path hierarchy of an organization
Hi,
The customer is asking to provide a report showing for each assignment of each employees the corresponding organization where it is assigned and the full path of the organization hierarchy.
The organization hierarchy is at most 6 level deep, so they want to produce the report with the columns:
root_organization | org_level1 | org_level2 | org_level3 | org_level4 | org_level5 | org_level6 | person_name | assignment_date
if the person is assigned in an organization lower than the 6th level, the remainin columns should be empty.
I see that the view HRFG_ORGANIZATION_HIERARCHIES returns only one step in the organizations hierarchy: Parent_organization_name, Child_organization_name.
Is there any view or function as well which returns the full path of an organization in the hierarchy? At least a function which returns the full path parents of the organization delimited by commas.
Thank youHi,
Yes, I wrote a custom code but is running a bit slowly for around 1000 organizations and more than 15 version of hierarcy (so 15000 rows of this view). I wanted to know if there is any optimized code provided by Oracle.
Thank you. -
Using WCF Cutom Adapter to return CLOB (or similar)
Hi all,
I am trying to return mulitple sets of data from an Oracle table each of which exceed VARCHAR2(4000).
I wish to do this in one call to a stored procedure as the intention is to assign the returned data to a messages body parts so that I can send them as multiple seperate attachments to an email (using the SMTP adapter).
My oracle stored procedure and returned data types are as follows:
PROCEDURE get_job(
po_job_id OUT jobs.job_id%TYPE, po_endpoint OUT data.endpoint%TYPE,
po_job_type OUT job_types.job_type_id%TYPE, po_data OUT rec_data_table);
TYPE rec_data_table IS TABLE OF rec_data
INDEX BY BINARY_INTEGER;
TYPE rec_data IS RECORD (
data CLOB
--data VARCHAR2(4000));
If I do restrict the data to VARCHAR2(4000), as shown commented out in the rec_data RECORD above everything works fine.
However, to return anything larger I believe would require me to return a CLOB (even though I would probably only be returning data of a few MBytes not GBytes).
Having tried this I get the following error:
"The adapter "WCF-Custom" raised an error message. Details "Microsoft.ServiceModel.Channels.Common.TargetSystemException: ORA-03113: end-of-file on communication channel
Process ID: 499868
Session ID: 201 Serial number: 33735 ---> Oracle.DataAccess.Client.OracleException: ORA-03113: end-of-file on communication channel
Process ID: 499868
Session ID: 201 Serial number: 33735"
I am using Oracle 11gR2, BizTalk 2010 and the WCF adapter with oracle bindings.
Researching this I find conflicting information:
"LOB types: The WCF-based Oracle DB adapter provides rich support for BLOB, CLOB and BFILE types in tables and stored procedures/functions. The adapter also exposes special operations for streaming BLOB/CLOB/BFILE data in the WCF service model
interface." Source: http://blogs.msdn.com/b/adapters/archive/2007/10/29/biztalk-oracle-adapter-vs-wcf-based-oracle-db-adapter.aspx
“Due to the limitation of associative arrays, PL/SQL tables or PL/SQL tables of records that contain any of the following data types are not supported in the Oracle Database adapter:
BFILE
BLOB
CLOB ……….”
Source: http://msdn.microsoft.com/en-us/library/dd788520.aspx
Also, this post (http://social.msdn.microsoft.com/Forums/en-US/303cc67c-5e01-4ecb-ba5c-184a1d73a7f7/biztalk-wcf-adpater-oracle-store-procedure-returning-clob?forum=biztalkediandas2) seems to indicate
it is possible but there is no detail so not sure if it matches my requirements.
I have also had a quick look at the
Operate_LOB sample but not sure if this will provide me with the solution I am after as I really wanted to return an array of CLOBS (or similar).
I have seen various other posts but nothing that definitively answers my questions and from my tests I would say that I can’t easily return largish amounts of data (a few MBs) in a single element
from Oracle …. unless of course I am missing something.
Can anyone give me a definitive answer as to whether I can do what I have set out above … if not I will turn my attention to a different solution.
Many Thanks for any help/advice you can provide,
Regards,
DaveFrom your description, it can hardly give precise troubleshooting for this problem, you can
consider opening a support case with us. Visit this link to see the various support options that are available to better meet your needs:
http://support.microsoft.com/default.aspx -
SOLVED: How can I use or call a function that returns %ROWTYPE?
Hi
edit: you can probably skip all this guff and go straight to the bottom...In the end this is probably just a question of how to use a function that returns a %rowtype. Thanks.
Currently reading Feuerstein's tome, 5th ed. I've downloaded and run the file genaa.sp, which is a code generator. Specifically, you feed it a table name and it generates code (package header and package body) that will create a cache of the specified table's contents.
So, I ran:
HR@XE> @"C:\Documents and Settings\Jason\My Documents\Work\SQL\OPP5.WEB.CODE\OPP5.WEB.CODE\genaa.sp"
749 /
Procedure created.
HR@XE> exec genaa('EMPLOYEES');which generated a nice bunch of code, viz:
create or replace package EMPLOYEES_cache is
function onerow ( EMPLOYEE_ID_in IN HR.EMPLOYEES.EMPLOYEE_ID%TYPE) return HR.EMPLOYEES%ROWTYPE;
function onerow_by_EMP_EMAIL_UK (EMAIL_in IN HR.EMPLOYEES.EMAIL%TYPE) return HR.EMPLOYEES%ROWTYPE;
procedure test;
end EMPLOYEES_cache;
create or replace package body EMPLOYEES_cache is
TYPE EMPLOYEES_aat IS TABLE OF HR.EMPLOYEES%ROWTYPE INDEX BY PLS_INTEGER;
EMP_EMP_ID_PK_aa EMPLOYEES_aat;
TYPE EMP_EMAIL_UK_aat IS TABLE OF HR.EMPLOYEES.EMPLOYEE_ID%TYPE INDEX BY HR.EMPLOYEES.EMAIL%TYPE;
EMP_EMAIL_UK_aa EMP_EMAIL_UK_aat;
function onerow ( EMPLOYEE_ID_in IN HR.EMPLOYEES.EMPLOYEE_ID%TYPE)
return HR.EMPLOYEES%ROWTYPE is
begin
return EMP_EMP_ID_PK_aa (EMPLOYEE_ID_in);
end;
function onerow_by_EMP_EMAIL_UK (EMAIL_in IN HR.EMPLOYEES.EMAIL%TYPE)
return HR.EMPLOYEES%ROWTYPE is
begin
return EMP_EMP_ID_PK_aa (EMP_EMAIL_UK_aa (EMAIL_in));
end;
procedure load_arrays is
begin
FOR rec IN (SELECT * FROM HR.EMPLOYEES)
LOOP
EMP_EMP_ID_PK_aa(rec.EMPLOYEE_ID) := rec;
EMP_EMAIL_UK_aa(rec.EMAIL) := rec.EMPLOYEE_ID;
end loop;
END load_arrays;
procedure test is
pky_rec HR.EMPLOYEES%ROWTYPE;
EMP_EMAIL_UK_aa_rec HR.EMPLOYEES%ROWTYPE;
begin
for rec in (select * from HR.EMPLOYEES) loop
pky_rec := onerow (rec.EMPLOYEE_ID);
EMP_EMAIL_UK_aa_rec := onerow_by_EMP_EMAIL_UK (rec.EMAIL);
if rec.EMPLOYEE_ID = EMP_EMAIL_UK_aa_rec.EMPLOYEE_ID then
dbms_output.put_line ('EMP_EMAIL_UK lookup OK');
else
dbms_output.put_line ('EMP_EMAIL_UK lookup NOT OK');
end if;
end loop;
end test;
BEGIN
load_arrays;
end EMPLOYEES_cache;
/which I have run successfully:
HR@XE> @"C:\Documents and Settings\Jason\My Documents\Work\SQL\EMPLOYEES_CACHE.sql"
Package created.
Package body created.I am now trying to use the functionality within the package.
I have figured out that the section
BEGIN
load_arrays;
end EMPLOYEES_cache;
/is the initialization section, and my understanding is that this is supposed to run when any of the package variables or functions are referenced. Is that correct?
With that in mind, I'm trying to call the onerow() function, but it's not working:
HR@XE> select onerow(100) from dual;
select onerow(100) from dual
ERROR at line 1:
ORA-00904: "ONEROW": invalid identifier
HR@XE> select employees_cache.onerow(100) from dual;
select employees_cache.onerow(100) from dual
ERROR at line 1:
ORA-06553: PLS-801: internal error [55018]
HR@XE> select table(employees_cache.onerow(100)) from dual;
select table(employees_cache.onerow(100)) from dual
ERROR at line 1:
ORA-00936: missing expressionHe provides the code genaa.sp, and a very brief description of what it does, but doesn't tell us how to run the generated code!
Now, I have just done some googling, and it seems that what I am trying to do isn't possible. Apparently %ROWTYPE is PL/SQL, and not understood by SQL, so you can't call onerow() from sql. Correct?
So I try wrapping the call in an exec:
HR@XE> exec select employees_cache.onerow(100) from dual;
BEGIN select employees_cache.onerow(100) from dual; END;
ERROR at line 1:
ORA-06550: line 1, column 30:
PLS-00382: expression is of wrong type
ORA-06550: line 1, column 7:
PLS-00428: an INTO clause is expected in this SELECT statement
HR@XE> exec select table(employees_cache.onerow(100)) from dual;
BEGIN select table(employees_cache.onerow(100)) from dual; END;
ERROR at line 1:
ORA-06550: line 1, column 14:
PL/SQL: ORA-00936: missing expression
ORA-06550: line 1, column 7:
PL/SQL: SQL Statement ignored
HR@XE> exec employees_cache.onerow(100)
BEGIN employees_cache.onerow(100); END;
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00221: 'ONEROW' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignoredNo joy.
Of course, now that I'm looking at it again, it seems that the way to go is indicated by the first error:
PLS-00428: an INTO clause is expected in this SELECT statement
So am I supposed to create a type of EMPLOYEES%ROWTYPE in a PL/SQL procedure, and the idea of this code, is that the first call to onerow() runs the initialiation code, which populates the cache, and all subsequent calls to onerow() (whether by my session or any other) will use the cache?
I've had a stab at this, but still, no joy:
create or replace procedure testcache is
emp employees%rowtype;
begin
select employees_cache.onerow(100) from dual into emp;
dbms_output.put_line('Emp id: ' || emp.employee_id);
end testcache;
show errors
HR@XE> @testcache.sql
Warning: Procedure created with compilation errors.
Errors for PROCEDURE TESTCACHE:
LINE/COL ERROR
4/9 PL/SQL: SQL Statement ignored
4/54 PL/SQL: ORA-00933: SQL command not properly ended
HR@XE>Have a feeling this should be really easy. Can anybody help?
Many thanks in advance.
Jason
Edited by: 942375 on 08-Feb-2013 11:45>
Ha, figured it out
>
Hopefully you also figured out that the example is just that: a technical example of how to use certain Oracle functionality. Unfortunately it is also an example of what you should NOT do in an actual application.
That code isn't scaleable, uses expensive PGA memory, has no limit on the amount of memory that might be used and, contrary to your belief will result in EVERY SESSION HAVING ITS OWN CACHE of exactly the same data if the session even touches that package.
Mr. Feuerstein is an expert in SQL and PL/SQL and his books cover virtually all of the functionality available. He also does an excellent job of providing examples to illustrate how that functionality can be combined and used. But the bulk of those examples are intended solely to illustrate the 'technical' aspects of the technology. They do not necessarily reflect best practices and they often do not address performance or other issues that need to be considered when actually using those techniques in a particular application. The examples show WHAT can be done but not necessarily WHEN or even IF a given technique should be used.
It is up to the reader to learn the advantages and disadvantages of each technicalogical piece and determine when and how to use them.
>
Now, I have just done some googling, and it seems that what I am trying to do isn't possible. Apparently %ROWTYPE is PL/SQL, and not understood by SQL, so you can't call onerow() from sql. Correct?
>
That is correct. To be used by SQL you would need to create SQL types using the CREATE TYPE syntax. Currently that syntax does not support anything similar to %ROWTYPE.
>
So am I supposed to create a type of EMPLOYEES%ROWTYPE in a PL/SQL procedure, and the idea of this code, is that the first call to onerow() runs the initialiation code, which populates the cache, and all subsequent calls to onerow() (whether by my session or any other) will use the cache?
>
NO! That is a common misconception. Each session has its own set of package variables. Any session that touches that package will cause the entire EMPLOYEES table to be queried and stored in a new associative array specifically for that session.
That duplicates the cache for each session using the package. So while there might be some marginal benefit for a single session to cache data like that the benefit usually disappears if multiple sessions are involved.
The main use case that I am aware of where such caching has benefit is during ETL processing of staged data when the processing of each record is too complex to be done in SQL and the records need to be BULK loaded and the data manipulated in a loop. Then using an associative array as a lookup table to quickly get a small amount of data can be effective. And if the ETL procedure is being processed in parallel (meaning different sessions) then for a small lookup array the additional memory use is tolerable.
Mitigating against that is the fact that:
1. Such frequently used data that you might store in the array is likely to be cached by Oracle in the buffer cache anyway
2. Newer versions of Oracle now have more than one cache
3. The SQL query needed to get the data from the table will use a bind variable that eliminates repeated hard parsing.
4. The cursor and the buffer caches ARE SHARED by multiple sessions globally.
So the short story is that there would rarely be a use case where ARRAYs like that would be preferred over accessing the data from the table. -
Can I use the value returned from a Text Function in another Formula?
I'm writing a report in Hyperion System 9 BI + Financial Reporting Studio version 9.2. I have 2 grids in my report.
Grid1 Column A is set up as a text function using the function type - <<GetCell("Grid2", 1, a, 1)>>. I would like to use the values returned from this text function in Column A (Grid 1) in a formula in Column B (Grid 1).
Is it possible to use the values returned in Column A of the text function in another formula? My report does not seem to recognize Column A as numerical values, even though the values to be returned are numerical.
If so, how do I recognize the values in Column A Grid 1 as numerical values and not text?
Thanks for any help you can offer!Hi Edson,
Yes you need to use the CALC_ERROR macro function to be able to test whether the last macro function returned an error. CALC_ERROR will return an 'X' if there an error occured during the execution of the last macro function.
You can use a macro similar to the following:
IF
CALC_ERROR( )
= 'X'
DO SOMETHING HERE
ENDIF
Let me explain how this works internally. The SAP system maintains a global variable g_flg_calc_error during the execution of macros in the planning book. The g_flg_calc_error variable will contain the value of f_calc_error that was set by the last macro function which executed. The ABAP coding of a planning book is something like this:
data: g_flg_calc_error type /SAPAPO/FLAG.
* SAP will pass g_flg_calc_error variable to all macro
* functions. When SAP calls a macro function, it does
* something like this.
call function '/SAPAPO/MACRO_FUNCTION_HERE'
exporting
plob_values = i_s_adv_plob_values
sdp_book = g_c_advf_sdp_book
sdp_view = g_c_advf_sdp_view
tables
cols_index = i_t_cols
value_tab = l_t_value_tab
changing
f_calc_error = g_flg_calc_error
As you can see, the g_flg_calc_error variable
is passed in the "changing" part of the call. The macro function being called can then use the f_calc_error
variable to change the value of the global
g_flg_calc_error variable. In fact, the macro function being called can also check (by looking at the f_calc_error variable) if the last macro function reported an error. The CALC_ERROR macro function just checks the value of f_calc_error parameter (w/c in fact is the value of the g_flg_calc_error variable) and returns "true/X" if the f_calc_error was set to true by the last macro function.
Hope this helps in clearing things out
Maybe you are looking for
-
How to restore my Ipod touch into a new hard disk/computer?
Guys, my Laptop's hard drive was crash and all my songs and applications were the only copy I had. However, I had no idea how to restore my musics and application back to the library after I had replace a new hard disk. I went through online to check
-
Is this possible to make work in ApEx?
Look at the link: http://www.comlinebrokers.com/index.php?id=5 "floating" table header is really amazing...is that possible to create in ApEx? THX!
-
I am using iweb and have been for some time to publish our website. I updated some PDF files today using inspector, enable as a hyperlink, select a file etc. This usually works very smoothly. I published the site, cleared my cache, then used safari t
-
Imported PNG Transparency Lost
I created an image in Photoshop that included a gradient layer fading from transparency to a foreground color (in this case, black). I saved this image as a PNG file and imported the file onto my Flash stage. The gradient appears on the image as expe
-
How to save data in html format while user click a save button in jsp page
Hi All, I have the following requirement If user click on the Save Button it should display a window which allows the user to select the directory and the data is stored in the Internet Explorer Format. Could please anybody suggest me how to impletme