Using CAST/COLLECT with a function
I have a select statement that gathers comments into a report by user ID and Project Name.
This works really well until I get to a point where the total comments exceeds 4000 characters, then I get a "character string buffer too small".
Is there another way to gather the comments and report on them in APEX?
Here is the Select Statement:
/** START SELECT
SELECT
PROJECT_NAME, USER_ID, COLLECT_FUNC(CAST(COLLECT (USER_NOTES) AS VARCHAR2_T)) as COMMENTS
FROM
TBL_PROJECT
where PROJ_DATE >= to_date('5/1/2011','MM/DD/YYYY') and PROJ_DATE <= to_date('6/30/2011','MM/DD/YYYY')
PROJECT_NAME, USER_ID
order by USER_ID;
/** END SELECT
Where the VARCHAR2_T is:
CREATE OR REPLACE TYPE "VARCHAR2_T" as table of varchar2(4000)
and the function that collects the comments is:
/*** START CODE
create or replace function collect_func (t in varchar2_t)
return varchar2
as
ret varchar(4000) := '';
i number;
begin
i := t.first;
while i is not null loop
if ret is not null then
ret := ret || ' -- <BR> ';
end if;
ret := ret || t(i);
i := t.next(i);
end loop;
return ret;
end;
/*** END CODE
SleepDeprivedInSeattle wrote:
I created a workspace at http://apex.oracle.com
The user name is: TEST_USER
Password is: myPassword1!You need to tell us the workspace name as well.
If you go to the SQL Workshop, SQL Commands window and try to execute:
SELECT
PROJECT_NAME, USER_ID, COLLECT_FUNC(CAST(COLLECT (COMMENTS_FLD) AS VARCHAR2_T)) as COMMENTS
FROM
TBL_PROJECT
group by PROJECT_NAME, USER_ID
order by USER_ID;
It will work for 10 row. But if you select 1000 rows, it fails because one of the projects has more than 4000 characters in the COMMENTS_FLD field. I expanded the VARCHAR to 6000 and it still fails.The VARCHAR2maximum size of <tt>VARCHAR2</tt> value that can be returned in Oracle SQL is 4000 bytes.
To return more than 4000 bytes, modify <tt>collect_func</tt> to return a CLOB, or use a different string aggregation technique. I normally (ab)use XMLDB for this as it:
<li>allows for either VARCHAR2 or CLOB output
<li>doesn't require any additional objects or privileges
<li>produces clean and properly structured XHTML without a lot of tedious and unreadable concatenations (my colleagues point out that it introduces a lot of tedious and unreadable XMLDB stuff instead)
SQL> select
2 d.deptno
3 , d.dname
4 , xmlserialize(
5 content
6 xmlelement(
7 "ul"
8 , xmlagg(
9 xmlelement("li", e.ename)
10 order by e.ename
11 )
12 )
13 as clob
14 indent size=2
15 ) employees
16 from
17 dept d
18 join emp e on d.deptno = e.deptno
19 group by
20 d.deptno
21 , d.dname
22 order by
23 d.deptno
24* , d.dname
SQL> /
DEPTNO DNAME EMPLOYEES
10 ACCOUNTING <ul>
<li>CLARK</li>
<li>KING</li>
<li>MILLER</li>
</ul>
20 RESEARCH <ul>
<li>ADAMS</li>
<li>JONES</li>
<li>SCOTT</li>
<li>SMITH</li>
</ul>
30 SALES <ul>
<li>ALLEN</li>
<li>BLAKE</li>
<li>JAMES</li>
<li>MARTIN</li>
<li>TURNER</li>
<li>WARD</li>
</ul>
40 OPERATIONS <ul>
<li>FORD</li>
</ul>Note that there is a 32K limit on the total size of a report row in APEX, including all data and mark-up.
Similar Messages
-
Unexpected "numeric or value error" when using CAST COLLECT
I am having trouble with string aggregation using CAST / COLLECT and the to_string function described on various sites around the net including AskTom and http://www.oracle-developer.net/display.php?id=306.
I am getting "numeric or value error: character string buffer too small" but cannot see which limit I am exceeding.
I have put together a simple test case to highlight this problem which I have pasted below.
The error does not seem to be coming from the to_string function itself (else I expect we would see "TO_STRING raised an exception" in the returned error message).
Any thoughts much appreciated,
Thanks, Andy
SQL*Plus: Release 10.1.0.4.2 - Production on Tue Jun 15 09:56:53 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> CREATE TYPE table_of_varchar2 AS TABLE OF VARCHAR2(32000);
2 /
Type created.
SQL> CREATE OR REPLACE FUNCTION to_string (
2 nt_in IN table_of_varchar2
3 , delimiter_in IN VARCHAR2 DEFAULT ',')
4 RETURN VARCHAR2
5 IS
6 l_idx PLS_INTEGER;
7 l_str VARCHAR2(32767);
8 l_dlm VARCHAR2(10);
9
10 BEGIN
11
12 l_idx := nt_in.FIRST;
13 WHILE l_idx IS NOT NULL LOOP
14 l_str := l_str || l_dlm || nt_in(l_idx);
15 l_dlm := delimiter_in;
16 l_idx := nt_in.NEXT(l_idx);
17 END LOOP;
18
19 RETURN l_str;
20 EXCEPTION
21 WHEN OTHERS THEN
22 raise_application_error(-20000
23 , 'TO_STRING raised an exception. '||
24 'The reported error was: '||sqlerrm);
25 END to_string;
26 /
Function created.
SQL> DECLARE
2 l_longstring varchar2(32000);
3 BEGIN
4 SELECT to_string(CAST( COLLECT( substr(object_name,1,1) ) AS table_of_varchar2 ) )
5 INTO l_longstring
6 FROM all_objects
7 WHERE rownum < 2001;
8
9 EXCEPTION
10 WHEN OTHERS THEN
11 raise_application_error(-20001
12 , 'The anonymous block raised an exception: '||
13 sqlerrm||'. '||DBMS_UTILITY.format_error_backtrace);
14 END;
15 /
PL/SQL procedure successfully completed.
SQL> DECLARE
2 l_longstring varchar2(32000);
3 BEGIN
4 SELECT to_string(CAST( COLLECT( substr(object_name,1,1) ) AS table_of_varchar2 ) )
5 INTO l_longstring
6 FROM all_objects
7 WHERE rownum < 2002;
8
9 EXCEPTION
10 WHEN OTHERS THEN
11 raise_application_error(-20001
12 , 'The anonymous block raised an exception: '||
13 sqlerrm||'. '||DBMS_UTILITY.format_error_backtrace);
14 END;
15 /
DECLARE
ERROR at line 1:
ORA-20001: The anonymous block raised an exception: ORA-06502: PL/SQL: numeric
or value error: character string buffer too small
ORA-06512: at line 1. ORA-06512: at line 1
ORA-06512: at line 4
ORA-06512: at line 11Aha, of course.
I was aware of the 4000 character SQL VARCHAR2 limit but didn't think it would apply here since we are calling a PLSQL function and trying to assign the value it returns into a PLSQL varchar2(32000) variable. BUT... we are of course doing this via a SELECT statement and hence via SQL. Therefore the SQL 4000 limit applies.
With this in mind, I changed the RETURN type of the to_string function to be CLOB. This solved the problem.
Thank you,
Andy -
Error using BULK Collect with RECORD TYPE
hello
I have written a simple Procedure by declaring a record type & then making a variable of NESTED Table type.
I then select data using BULK COLLECT & tryin to access it through a LOOP.....Getting an ERROR.
CREATE OR REPLACE PROCEDURE sp_test_bulkcollect
IS
TYPE rec_type IS RECORD (
emp_id VARCHAR2(20),
level_id NUMBER
TYPE v_rec_type IS TABLE OF rec_type;
BEGIN
SELECT employee_id, level_id
BULK COLLECT INTO v_rec_type
FROM portfolio_exec_level_mapping
WHERE portfolio_execp_id = 2851852;
FOR indx IN v_rec_type.FIRST..v_rec_type.LAST
LOOP
dbms_output.put_line('Emp -- '||v_rec_type.emp_id(indx)||' '||v_rec_type.level_id(indx));
END LOOP;
END;
Below are the ERROR's i am getting ....
- Compilation errors for PROCEDURE DOMRATBDTESTUSER.SP_TEST_BULKCOLLECT
Error: PLS-00321: expression 'V_REC_TYPE' is inappropriate as the left hand side of an assignment statement
Line: 15
Text: FROM portfolio_exec_level_mapping
Error: PL/SQL: ORA-00904: : invalid identifier
Line: 16
Text: WHERE portfolio_execp_id = 2851852;
Error: PL/SQL: SQL Statement ignored
Line: 14
Text: BULK COLLECT INTO v_rec_type
Error: PLS-00302: component 'FIRST' must be declared
Line: 19
Text: LOOP
Error: PL/SQL: Statement ignored
Line: 19
Text: LOOP
PLZ Help.and with a full code sample:
SQL> CREATE OR REPLACE PROCEDURE sp_test_bulkcollect
2 IS
3 TYPE rec_type IS RECORD (
4 emp_id VARCHAR2(20),
5 level_id NUMBER
6 );
7 TYPE v_rec_type IS TABLE OF rec_type;
8 v v_rec_type;
9 BEGIN
10 SELECT empno, sal
11 BULK COLLECT INTO v
12 FROM emp
13 WHERE empno = 7876;
14 FOR indx IN v.FIRST..v.LAST
15 LOOP
16 dbms_output.put_line('Emp -- '||v(indx).emp_id||' '||v(indx).level_id);
17 END LOOP;
18 END;
19 /
Procedure created.
SQL>
SQL> show error
No errors.
SQL>
SQL> begin
2 sp_test_bulkcollect;
3 end;
4 /
Emp -- 7876 1100
PL/SQL procedure successfully completed. -
Problem with SSAS cube reporting action when using pivot filter with cubevalue function
Hi everyone,
I have a quite specific problem when I combine cube actions (Reporting Action SSRS) with Excel's cubevalue() function.
The problem is when I use a pivot filter as a parameter for the cubevalue() function. The action item does not show up in the context menue.
The cube action works fine when I do it from a "normal" pivot or if I use the cubevalue() function without the reference to a pivot filter (all the parameters in the function are "hard-coded").
I use SSAS 2012 and Excel 2010.
Thanks for yor help.
GerhardHi everyone,
I actually figured out a way to solve this problem. I had to use a detour to solve this bug in Excel (at least I think it's a bug).
What I needed to do: I had to make Excel belive that the filter is actuall hard-coded and does not come from a pivot filter. This was only possible by adding a new calculated measure to the cube that gives back the MEMBER_Unique_Name to the current member
passed. This "value" can then be used to go back to the cube and select the cubemember function. Here is a small example.
This is the cube member:
CREATE MEMBER CURRENTCUBE.[Measures].[RegCompBranNameKey] AS
[Company Branch].[Reg - Comp - Bran Name].CurrentMember.Properties("MEMBER_UNIQUE_NAME", TYPED),
VISIBLE = 0 ;
And this is then done in a hidden Excel cell:
=CUBEMEMBER("Metrics";
IF(RIGHT(CUBEVALUE("Metrics";<PivotFilter>;"[Measures].[RegCompBranNameKey]");5)="[ALL]";"[ALL]";
RIGHT(CUBEVALUE("Metrics";<PivotFilter>;"[Measures].[RegCompBranNameKey]");LEN(CUBEVALUE("GlobalMetrics";<PivotFilter>;"[Measures].[RegCompBranNameKey]"))-57)
I had to use the UniqueName property because I have a combined filter. That's also the reason for this truncation and also useing the last part of it. If you just have a straight key you more easily use it. -
How to use object collection with linked objects
<p>Hi,</p><p>I'm using VS2005 Crystal reports in a c# client app (server has database, but client does not have!). So the use of the objects transfered to the client seemed to me a good solution for showing reports on the client. The objects mostly link to several other objects (properties of type <type> or properties of type [] <type>) and the links are correctly configured in database assistant.</p><p>But: Whenever using one of the linked fields, all of the main fields will never show up in the report.</p><p>So, what is the correct way of showing a master / detail report using linked object collections???</p><p> (A small test sample app can be provided upon request)</p><p> TIA</p><p>BP</p>
What database and connection type are you using? Are you connecting the report directly to the database, or trying to assign the datasource to object data?
It sounds like you might be trying to use a linked list, collection or other C# construct to pass your data in. This currently isn't supported by the Crystal Reports SDK. You can use a DataSet or a DataTable, and possibly also an IDataReader depending on which version of Crystal Reports you're referencing in your project. Of course you can also connect directly to the database, even if the database isn't on the same machine as the application.
The way to show master records with detail information is through the use of subreports and linked subreport parameters. Linked subreports take their parameter value from a record in the main report, so that only the data appropriate to that master record is displayed. The guys over in the [report design|SAP Crystal Reports; forum can help you out with this if you have questions on the specifics. -
How to handle the bad record while using bulk collect with limit.
Hi
How to handle the Bad record as part of the insertion/updation to avoid the transaction.
Example:
I am inserting into table with LIMIT of 1000 records and i've got error at 588th record.
i want to commit the transaction with 588 inserted record in table and log the error into
error logging table then i've to continue with transaction with 560th record.
Can anyone suggest me in this case.
Regards,
yuva>
How to handle the Bad record as part of the insertion/updation to avoid the transaction.
>
Use the SAVE EXCEPTIONS clause of the FORALL if you are doing bulk inserts.
See SAVE EXCEPTIONS in the PL/SQL Language doc
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/tuning.htm
And then see Example 12-9 Bulk Operation that continues despite exceptions
>
Example 12-9 Bulk Operation that Continues Despite Exceptions
-- Temporary table for this example:
CREATE TABLE emp_temp AS SELECT * FROM employees;
DECLARE
TYPE empid_tab IS TABLE OF employees.employee_id%TYPE;
emp_sr empid_tab;
-- Exception handler for ORA-24381:
errors NUMBER;
dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(dml_errors, -24381);
BEGIN
SELECT employee_id
BULK COLLECT INTO emp_sr FROM emp_temp
WHERE hire_date < '30-DEC-94';
-- Add '_SR' to job_id of most senior employees:
FORALL i IN emp_sr.FIRST..emp_sr.LAST SAVE EXCEPTIONS
UPDATE emp_temp SET job_id = job_id || '_SR'
WHERE emp_sr(i) = emp_temp.employee_id;
-- If errors occurred during FORALL SAVE EXCEPTIONS,
-- a single exception is raised when the statement completes.
EXCEPTION
-- Figure out what failed and why
WHEN dml_errors THEN
errors := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.PUT_LINE
('Number of statements that failed: ' || errors);
FOR i IN 1..errors LOOP
DBMS_OUTPUT.PUT_LINE('Error #' || i || ' occurred during '||
'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
DBMS_OUTPUT.PUT_LINE('Error message is ' ||
SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;
DROP TABLE emp_temp; -
Dont want to use group by with sum function..
Hi all
I am using sum function but i dont want to use group by since my query give me following output which i dont want I want.
0------------22---------(null) Furniture
0----------- 3700------ (null) अनपेड बिल्स देणे
15800-----14202-----(null) Petty Cash
(null)------ (null)------ 9109 Furniture
(null)------ (null)------ 1789 Petty Cash
(null)-------(null)------ 0 Checking In-Transfer
I want like
0------------22---------9109 Furniture
0----------- 3700------ 0 अनपेड बिल्स देणे
15800-----14202-----1789 Petty Cash
what should be the problem how I can handle the query my query is
select null as totalcr, null as totaldr, (sum(acct.amtsourcecr)-sum(acct.amtsourcedr)) as opening , ev.name as accountname
from fact_acct acct right OUTER join c_elementvalue ev on acct.account_id= ev.c_elementvalue_id
where acct.dateacct < '01/04/2010'
and ev.cr_account_base=2
group by ev.name
UNION
select sum(acct.amtsourcecr) as totalcr, sum(acct.amtsourcedr) as totaldr, null as opening
*,ev.name as accountname*
from fact_acct acct right OUTER join c_elementvalue ev on acct.account_id= ev.c_elementvalue_id
where acct.datetrx BETWEEN '01/04/2010' and '01/04/2010'
group by ev.name
if I remove group by it shows me error .....not a single group by function ...
please help me out ,,,
thanking youThis is one way you can do it without a group by:
SQL> with t as
2 (
3 select 0 amt1, 22 amt2, null amt3, 'Furniture' tag from dual union all
4 select 15800,14202,null, 'Petty Cash' from dual union all
5 select null, null, 9109, 'Furniture' from dual union all
6 select null, null, 1789, 'Petty Cash' from dual
7 )
8 select tag, amt1, amt2, amt3
9 from
10 (
11 select sum(amt1) over (partition by tag) amt1
12 ,sum(amt2) over (partition by tag) amt2
13 ,sum(amt3) over (partition by tag) amt3
14 ,first_value(t.tag) over (partition by t.tag order by rownum) tag
15 ,row_number() over (partition by t.tag order by rownum) rn
16 from t
17 )
18 where rn = 1
19 /
TAG AMT1 AMT2 AMT3
Furniture 0 22 9109
Petty Cash 15800 14202 1789 -
How to improve performance using bulk collects with plsql tables or arrays
Hi All,
my procedure is like this
declare
cursor c1 is select ----------------------
begin
assigning to variables
validations on that variables
--50 validations are here --
insert into a table
end;
we have created indexes on primary keys,
i want to use
DECLARE
CURSOR a_cur IS
SELECT program_id
FROM airplanes;
TYPE myarray IS TABLE OF a_cur%ROWTYPE;
cur_array myarray;
BEGIN
OPEN a_cur;
LOOP
FETCH a_cur BULK COLLECT INTO cur_array LIMIT 100;
***---------can i assign cursor data to the plsql table variables or array***
***validate on the pl sql variable as---***
i
nsert into a table
EXIT WHEN a_cur%NOTFOUND;
END LOOP;
CLOSE a_cur;
END;
Edited by: Veekay on Oct 21, 2011 4:28 AMFastest way often is this:
insert /*+append */
into aTable
select * from airplanes;
commit;The select and insert part can even be done in parallel if needed.
However if the oparation is complex or the dataset is very very very very very large or the programmer is decent but not excellent then the bulk approach should be considered. It is often a pretty stable and linear scaling approach.
The solution depends a little on the database version.
LOOP
FETCH a_cur BULK COLLECT INTO cur_array LIMIT 100;
EXIT WHEN a_cur.count = 0;
forall i in a_cur.first.. a_cur.last
insert into aTable (id)
values (a_cur(i));
END LOOP;
...If you have more then one column then you might need a single collection for each column. Other possibilities depend on the db version.
Also: do not exit using a_cur%NOTFOUND. This is wrong! You might loose records from the end of the data set. -
Using Adobe Form with SRM Functionality.
Hi Friends,
Our client wants to achieve the total functionality of SRM Purchase Order and Shopping cart through Adobe Form.I would like to know if any of you have come across such a scenario where Adobe Form has been used to replicate SRM purchase Order and Shopping Cart functionality.
It would be a great help to us if you kindly share your experience of the above scenarios.
Thanks in advance.
Best Regards,
KoushikNote 1264423 - Customizing for print forms in SRM 7.0
Summary
Symptom
New functionality/Enhancements provided in SRM 7.0 for print forms is only
available in the SAP Interactive forms by ADobe and is not available in
Smartforms delivered by SRM.
More Terms
PDF based forms, ADB, Adobe forms, Confirmation, BBP_CONF_ADB, SAP
Interactive forms by Adobe, Output, SRM-EBP-CA-PRT, SRM-EBP-CGS
Cause and Prerequisites
All new enhancements or functionalities are supported only in SAP
Interactive forms by Adobe which is delivered as part of the SRM 7.0. The
Smartforms deliverd in previous verions would not have any new enhancements
from SRM 7.0.
So it is recommended to use the new SAP interactive forms By Adobe instead
of the Smartforms for print and output in SRM 7.0.
Solution
The customizing required to switch to the new SAP interactive forms by
Adobe are described avaiable as part of the customization documentation
againt the IMG entries for Output:
the documentation and the respecitive customizing can be accesed in the
following manner:
Step 1:
Goto transaction SPRO -> SAP Reference IMG -> SAP Supplier relationship
Management -> SRM Server -> Cross Application basic settings -> Set output
Actions and output Format -> Define Actions for Document output.
maintain the action defentions for all purchasing documents for which the
new forms are intended to be used in the above mentioned customizing.
Save the customizing
Step 2:
Goto transaction SPRO -> SAP Reference IMG -> SAP Supplier relationship
Management -> SRM Server -> Cross Application basic settings -> Set output
Actions and output Format -> Condition-Dependent Document Output.
maintain the conditions for output for all purchasing documents for which
the new forms are intended to be used in the above mentioned customizing.
Save the customizing.
For more details on each of the above mentioned steps access the
corresponding documentation againt the respective customizing entry in
SPRO.
Release Status: Released for Customer
Released on: 30.10.2008 11:23:10
Priority: Recommendations/additional info
Category: Customizing
Main Component SRM-EBP-CA-PRT Document Output / Forms
Valid Releases
Software Component Release From
Release
To Release and Following
SRM_SERVER 700 700 700
regards
Muthu -
Using bulk collect with select
i am working on oracle 10g release 2 .
My requirement is like this
1 declare
2 type id_type is table of fnd_menus.menu_id%type;
3 id_t id_type;
4 cursor cur_menu is select menu_name from menu;
5 type name_type is table of menu.menu_name%type;
6 name_t name_type;
7 begin
8 open cur_menu;
9 fetch cur_menu bulk collect into name_t;
10 forall i in name_t.first..name_t.last
11 select menu_id into id_t(i) from fnd_menus where menu_name = name_t(i);
12* end;
SQL> /
select menu_id into id_t(i) from fnd_menus where menu_name = name_t(i);
ERROR at line 11:
ORA-06550: line 11, column 23:
PLS-00437: FORALL bulk index cannot be used in INTO clause
ORA-06550: line 11, column 31:
PL/SQL: ORA-00904: : invalid identifier
ORA-06550: line 11, column 3:
PL/SQL: SQL Statement ignoredSo how i can bulk select into a table the rows that satisfy a particular condition ?A forall statement is used bulk execute DML, as can be read [url http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/forall_statement.htm#LNPLS01321]here in the documentation.
I guess you want something like this:
SQL> create table menu
2 as
3 select 'A' menu_name from dual union all
4 select 'B' from dual union all
5 select 'C' from dual
6 /
Tabel is aangemaakt.
SQL> create table fnd_menus
2 as
3 select 10 menu_id, 'A' menu_name from dual union all
4 select 9, 'B' from dual union all
5 select 8, 'C' from dual union all
6 select 7, 'D' from dual
7 /
Tabel is aangemaakt.
SQL> declare
2 type id_type is table of fnd_menus.menu_id%type;
3 id_t id_type;
4 cursor cur_menu is select menu_name from menu;
5 type name_type is table of menu.menu_name%type;
6 name_t name_type;
7 begin
8 open cur_menu;
9 fetch cur_menu bulk collect into name_t;
10 forall i in name_t.first..name_t.last
11 select menu_id into id_t(i) from fnd_menus where menu_name = name_t(i);
12 end;
13 /
select menu_id into id_t(i) from fnd_menus where menu_name = name_t(i);
FOUT in regel 11:
.ORA-06550: Regel 11, kolom 25:
PLS-00437: FORALL-bulkindex kan niet worden gebruikt in INTO-clausule..
ORA-06550: Regel 11, kolom 33:
PL/SQL: ORA-00904: : ongeldige ID.
ORA-06550: Regel 11, kolom 5:
PL/SQL: SQL Statement ignored.
SQL> declare
2 type id_type is table of fnd_menus.menu_id%type;
3 id_t id_type;
4 begin
5 select menu_id
6 bulk collect into id_t
7 from fnd_menus
8 where menu_name in (select menu_name from menu)
9 ;
10 for i in 1..id_t.count
11 loop
12 dbms_output.put_line(id_t(i));
13 end loop
14 ;
15 end;
16 /
10
9
8
PL/SQL-procedure is geslaagd.Regards,
Rob. -
Using an array with a function
Hi all,
I'm working on an order form where users choose a course they want to order from a drop-down list, then enter the number of licences they require. I'm trying to build in a 'volume-based' discount model the form, and would like to ask for some help in using arrays and how to use them in functions. I'm very new to this, and would appreciate any help you can provide!
Basically, we have 3 products that can be ordered on the same form, and all have different discount models (i.e you get a different % discount for different numbers of licences ordered, depending on the course chosen). I'm storing the discount models in 3 separate two-dimensional arrays, then want to create a function that takes two parameters - the name of the array and the volume that the customer orders - to calculate the appropriate discount. I would then call the function on the change events of either the drop down list or the licence qty field.
Below is my attempt so far (only one array here, but the others are the same syntax). This is held in a script object called DiscountCalculator in the form. The idea of the function is to loop through the array until it finds the correct course, then loop through the value field until it finds the correct discount:
//code holds the discount model for each course in a 2 dimensional array. A new array is needed for each course.
//Course 1
var
Course1Array = new Array(3);
Course1Array[0]
= new Array(2);Course1Array[0][0]
= "49"; //'breakpoint' at which discount is appliedCourse1Array[0][1]
= "0"; //discount % given for this no of licences
Course1Array[1]
= new Array(2);Course1Array[1][0]
= "99";Course1Array[1][1]
= "20";
Course1Array[2]
= new Array(2);Course1Array[2][0]
= "199";Course1Array[2][1]
= "25";
function
CalculateDiscount(CourseArray, value){
for
(var i = 0; i <= CourseArray.length; i++){
if
(value <= CourseArray[i][0]){
return CourseArray[i][1]}
I can use a MessageBox to return a specified value from the array on the click event, so that seems to be set up correctly. But when I try to tcall the function in the change event of the drop-down list on the form:
DiscountCalculator.CalculateDiscount(fldCourse.rawvalue, fldqty.rawvalue)
It doesn't work, usually complaining that "Course1Array is not defined". I think it must be some kind of syntax error, but I have trawled the internet looking for some examples and can't find any.
I'd be grateful for any assistance.
Thanks
MattIt might be easy to solve these issues if you post your form.
Post your form if it doesn't contain any confidential information.
Nith -
Opening two cursors using open cursor with bulk collect on colections ..
Is it possible to have the implementatiion of using bulk collect with collections using two open cursors ..
first c1
second c2
open c1
loop
open c2
loop
end loop
close c2
end loop;
close c1
what i found is for every outer loop of cursor c1 , cursor c2 is open and closed for every record.
is this willl imporove the performace .?
EXAMPLE:-
NOTE: The relatoin between finc and minc is one to many ..finc is parent and minc is child
function chk_notnull_blank ( colname IN number ) return number is
BEGIN
if ( colname is NOT NULL and colname not in ( -8E14, -7E14, -6E14, -5E14, -4E14, -3E14, -2E14, -1E14, -1E9 )) then
RETURN colname ;
else
RETURN 0;
end if;
END chk_notnull_blank;
procedure Proc_AnnualFmlyTotIncSummary is
CURSOR c_cur_finc IS SELECT FAMID FROM FINC ;
CURSOR c_cur_minc IS SELECT FAMID, MEMBNO , ANFEDTX, ANGOVRTX, ANPRVPNX, ANRRDEDX, ANSLTX, SALARYX, SALARYBX, NONFARMX, NONFRMBX , FARMINCX, FRMINCBX, RRRETIRX, RRRETRBX, SOCRRX, INDRETX, JSSDEDX, SSIX, SSIBX from MINC minc WHERE FAMID IN ( SELECT FAMID FROM FINC finc WHERE minc.FAMID = finc.FAMID );
v_tot_fsalaryx number := 0;
v_tot_fnonfrmx number := 0;
v_tot_ffrmincx number := 0;
v_tot_frretirx number := 0;
v_tot_findretx number := 0;
v_tot_fjssdedx number := 0;
v_tot_fssix number := 0;
v_temp_sum_fsalaryx number := 0;
v_temp_sum_fnonfrmx number := 0;
v_temp_sum_ffrmincx number := 0;
v_temp_sum_frretirx number := 0;
v_temp_sum_findretx number := 0;
v_temp_sum_fjssdedx number := 0;
v_temp_sum_fssix number := 0;
TYPE minc_rec IS RECORD (FAMID MINC.FAMID%TYPE, MEMBNO MINC.MEMBNO%TYPE , ANFEDTX MINC.ANFEDTX%TYPE, ANGOVRTX MINC.ANGOVRTX%TYPE , ANPRVPNX MINC.ANPRVPNX%TYPE , ANRRDEDX MINC.ANRRDEDX%TYPE , ANSLTX MINC.ANSLTX%TYPE, SALARYX MINC.SALARYX%TYPE , SALARYBX MINC.SALARYBX%TYPE , NONFARMX MINC.NONFARMX%TYPE , NONFRMBX MINC.NONFRMBX%TYPE, FARMINCX MINC.FARMINCX%TYPE , FRMINCBX MINC.FRMINCBX%TYPE , RRRETIRX MINC.RRRETIRX%TYPE , RRRETRBX MINC.RRRETRBX%TYPE, SOCRRX MINC.SOCRRX%TYPE , INDRETX MINC.INDRETX%TYPE , JSSDEDX MINC.JSSDEDX%TYPE , SSIX MINC.SSIX%TYPE , SSIBX MINC.SSIBX%TYPE );
v_flag_boolean boolean := false;
v_famid number ;
v_stmt varchar2(3200) ;
v_limit number := 50;
v_temp_FAMTFEDX number := 0 ;
v_temp_FGOVRETX number := 0 ;
v_temp_FPRIVPENX number := 0 ;
v_temp_FRRDEDX number := 0 ;
v_temp_FSLTAXX number := 0 ;
v_temp_FSALARYX number := 0 ;
v_temp_FNONFRMX number := 0 ;
v_temp_FFRMINCX number := 0 ;
v_temp_FRRETIRX number := 0 ;
v_temp_FINDRETX number := 0 ;
v_temp_FJSSDEDX number := 0 ;
v_temp_FSSIX number := 0 ;
BEGIN
OPEN c_cur_finc ;
LOOP
FETCH c_cur_finc BULK COLLECT INTO famid_type_tbl LIMIT v_limit;
EXIT WHEN famid_type_tbl.COUNT = 0;
FOR i in famid_type_tbl.FIRST..famid_type_tbl.LAST
LOOP
OPEN c_cur_minc ;
LOOP
FETCH c_cur_minc BULK COLLECT INTO minc_rec_type_tbl LIMIT v_limit;
EXIT WHEN minc_rec_type_tbl.COUNT = 0;
FOR j IN minc_rec_type_tbl.FIRST..minc_rec_type_tbl.LAST
LOOP
if ( famid_type_tbl(i) = minc_rec_type_tbl(j).FAMID ) THEN
v_temp_FAMTFEDX := v_temp_FAMTFEDX + chk_notnull_blank(minc_rec_type_tbl(j).ANFEDTX );
v_temp_FGOVRETX := v_temp_FGOVRETX + chk_notnull_blank(minc_rec_type_tbl(j).ANGOVRTX);
v_temp_FPRIPENX := v_temp_FPRIPENX + chk_notnull_blank(minc_rec_type_tbl(j).ANPRVPNX);
v_temp_FRRDEDX := v_temp_FRRDEDX + chk_notnull_blank(minc_rec_type_tbl(j).ANRRDEDX);
v_temp_FSLTAXX := v_temp_FSLTAXX + chk_notnull_blank(minc_rec_type_tbl(j).ANSLTX );
v_temp_FSALARYX := v_temp_FSALARYX + chk_notnull_blank(minc_rec_type_tbl(j).SALARYX ) + chk_notnull_blank(minc_rec_type_tbl(j).SALARYBX);
v_temp_FNONFRMX := v_temp_FNONFRMX + chk_notnull_blank(minc_rec_type_tbl(j).NONFARMX) + chk_notnull_blank(minc_rec_type_tbl(j).NONFRMBX);
v_temp_FFRMINCX := v_temp_FFRMINCX + chk_notnull_blank(minc_rec_type_tbl(j).FARMINCX) + chk_notnull_blank(minc_rec_type_tbl(j).FRMINCBX );
v_temp_FRRETIRX := v_temp_FRRETIRX + chk_notnull_blank(minc_rec_type_tbl(j).RRRETIRX) + chk_notnull_blank(minc_rec_type_tbl(j).RRRETRBX ) + chk_notnull_blank(minc_rec_type_tbl(j).SOCRRX);
v_temp_FINDREXT := v_temp_FINDRETX + chk_notnull_blank(minc_rec_type_tbl(j).INDRETX);
v_temp_FJSSDEDX := v_temp_FJSSDEDX + chk_notnull_blank(minc_rec_type_tbl(j).JSSDEDX);
v_temp_FSSIX := v_temp_FSSIX + chk_notnull_blank(minc_rec_type_tbl(j).SSIX ) + chk_notnull_blank(minc_rec_type_tbl(j).SSIBX);
END IF;
END LOOP;
END LOOP ;
CLOSE c_cur_minc;
UPDATE FINC SET FAMTFEDX = v_temp_FAMTFEDX WHERE FAMID = famid_type_tbl(i);
END LOOP;
END LOOP;
CLOSE c_cur_finc;
END;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
v_err_code := SQLCODE;
v_err_msg := substr(SQLERRM, 1, 200);
INSERT INTO audit_table (error_number, error_message) VALUES (v_err_code, v_err_msg);
error_logging(p_error_code => substr(sqlerrm,1,9), p_error_message => substr(sqlerrm,12), p_package =>'PKG_FCI_APP',p_procedure => 'Proc_Annual_Deductions_FromPay ' , p_location => v_location);
end Proc_AnnualFmlyTotIncSummary ;
Is the proga efficient and free from compilation errors ..?
thanks/kumar
Edited by: kumar73 on Sep 22, 2010 12:48 PMfunction chk_notnull_blank ( colname IN number ) return number is Maybe this function should have its own forum:
how to use case in this program
Re: how to declare a formal parameter in a function of type record and access ?
Re: how to define a function with table type parameter
Re: creation of db trigger with error ..
Re: How to write a trigger for the below scenario
how to improve the code using advanced methods
yours advice in improving the coding ..
How to use bulk in multiple cursors !!
;-) -
TABLE FUNCTION OR CAST WITH TABLE FUNCTION
Consider following scenario:
I've a function which returns nested table of employees.
I am calling this function in some other procedure and building a query dynamically.
Sample code looks like
CREATE OR REPLACE PROCEDURE TEST_PROC( P_EMP_ID IN NUMBER,
O_EMP_LIST OUT SYS_REFCURSOR) IS
v_tbl_emp_id tbl_emp_id;
begin
v_tbl_emp_id := fn_get_usr_list (P_EMP_ID);--fetches employee id reporting to given emp id
v_select_clause :=
'SELECT EMP_NO,EMP_NAME,DEPT_NO';
v_from_clause := ' FROM EMP';
v_where_clause1 :=
' WHERE emp_no IN (
SELECT COLUMN_VALUE
FROM TABLE
(CAST
(:v_tbl_emp_id AS tbl_emp_id
--AND I AM APPENDING AND CLAUSES BASED ON VARIOUS CONDITION
v_qry := v_select_clause || v_from_clause|| v_where_clause1;
OPEN O_EMP_LIST FOR v_qry USING v_tbl_emp_id;
END TEST_PROC;I CAN REWRITE THE SAME CODE AS
CREATE OR REPLACE PROCEDURE TEST_PROC( P_EMP_ID IN NUMBER,
O_EMP_LIST OUT SYS_REFCURSOR) IS
begin
v_select_clause :=
'SELECT EMP_NO,EMP_NAME,DEPT_NO';
v_from_clause := ' FROM EMP';
v_where_clause1 :=
' WHERE emp_no IN (
SELECT COLUMN_VALUE
FROM TABLE(fn_get_usr_list (:P_EMP_ID)))';
--AND I AM APPENDING AND CLAUSES BASED ON VARIOUS CONDITION
v_qry := v_select_clause || v_from_clause|| v_where_clause1;
OPEN O_EMP_LIST FOR v_qry USING P_EMP_ID;
END TEST_PROC;Now I would like to know which one performs better
USING TABLE ALONE OR USING CAST ALONG WITH THE TABLE FUNCTION?
AND PLEASE HELP ME ON FORMATTING CODE.
I've added tags still its not formatting!!
Thanks,
NM
Edited by: user10862473 on Apr 11, 2011 12:14 AM
Edited by: BluShadow on 11-Apr-2011 09:13
fixed {noformat}{noformat} tagsTo be sure which is better you will have to test them both. You can use either AUTOTRACE or Oracle trace (tkprof) to get run metrics - system resources used when running both versions of the query. AUTOTRACE won't provide CPU information, but if you can find the qieries in (G)V$SQL you can find it there. Oracle trace is more effort but should provide more metrics. I could do it if I have privileges :(..
All I can do is check the time taken by the both procedures using set timing on, which gives same result for both.
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.07Thanks,
NM -
Using Starts-with XSLT function with XI
Hi All,
Any help is apperciated. I am using the starts-with xslt function and when i do so the message gets stucks in the queue. If i run code without the starts-with then is works??
<xsl:for-each select="receipt/prod">
<xsl:for-each select="carrier/carrier_detail/carrier">
<xsl:choose>
<xsl:when test="carrier_type='CASE'">
<xsl:choose>
<xsl:when test="starts-with(carrier_barcode, '00')">
do something
</xsl:when>
<otherwise>
do something
</otherwise>
so on..
when i try to process messsage using this xslt format it gets sysfail in the queue, but without it, it works fine.
I need to a special format if the condition of barcode starts with 00Chirag,
Create xslt on abap mapping using transaction SXLT_TOOL on XI abap stack. Copy paste same xslt code and run with test file. You can debug code or most likely you can see error message too.
Actually your mapping raising an exception which result in sys-fail.
Hope this will help.
Nilesh -
Having clause with Analytic function
can you pls let me know if we can use HAVING clause with analytic function
select eid,empno,sum(sal) over(partition by year)
from employee
where dept = 'SALES'
having sum(sal) > 10000I m getting error while using the above,
IS that we can use HAVING clause with partition by
Thanks in advanceYour having clause isn't using an analytical function, is using a regular aggregate function.
You also can't use analytical functions in the where clause or having clause like that as they are windowing functions and belong at the top of the query.
You would have to wrap the query to achieve what you want e.g.
SQL> ed
Wrote file afiedt.buf
1 select deptno, total_sal
2 from (
3 select deptno,sum(sal) over (partition by deptno) as total_sal
4 from emp
5 )
6 group by deptno, total_sal
7* having total_sal > 10000
SQL> /
DEPTNO TOTAL_SAL
20 10875
SQL>
Maybe you are looking for
-
Inbound Order with Quotation as reference
We are receiving inbound orders with reference to quotation. 1) Quotation has 3 line item. 2) IDoc has 2 line item(totally different material and diff qty) Sales order created succesfully with 5(3 from quotation + 2 from idoc) line item. No matter m
-
Attaching a commercial activity with a contract.
Hi, I have a requirement to remove a commercial activity from an existing contract in CRM and re-tag with a new contract. Is the function module CRM_ORDER_MAINTAIN is going to help in this purpose? If it does, can I have some clue like which paramet
-
MB pro Airport utililty cannot recongnize my AX in remote base mode
I set up my AX as remote base of a existent wirless d link network, it worked for 2 days and now it is no more recognized from my macbook, is there an recent update trouble? Can u help me please?
-
Ipod is not recognizing my passcode, please help!
This is the second time I have put a passcode lock on my ipod. I just put a passcode on my ipod about 10 minutes ago. I know I have not forgotten what it is because I wrote it down and it is the same password as last time. Not it says "Ipod diasbled"
-
Music stops playing after 30 seconds, I can change the song but nothing sounds and time line continues working.