Home » Developer & Programmer » Forms » forms-mask based on stored procedure ?
forms-mask based on stored procedure ? [message #85213] |
Wed, 09 June 2004 12:12 ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
hudo
Messages: 165 Registered: May 2004
|
Senior Member |
|
|
Hello,
can I base a forms-mask directly on a SELECT-Statement respectively on a stored procedure ?
The following scenario:
CREATE TABLE COL_TABLE
(COL1 VARCHAR2(10),
COL2 VARCHAR2(10),
COL3 VARCHAR2(10),
COL4 DATE,
COL5 NUMBER(4));
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA1','1',TO_DATE('01.02.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA1','1',TO_DATE('01.02.2003','dd.mm.yyyy'),60);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA1','1',TO_DATE('01.05.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA1','2',TO_DATE('01.05.2003','dd.mm.yyyy'),50);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA1','2',TO_DATE('01.05.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA2','1',TO_DATE('01.02.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA2','1',TO_DATE('01.05.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA2','3',TO_DATE('01.02.2003','dd.mm.yyyy'),40);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA3','2',TO_DATE('01.07.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA3','2',TO_DATE('01.02.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('AAA','STA3','2',TO_DATE('01.05.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('BBB','STA1','1',TO_DATE('01.07.2003','dd.mm.yyyy'),11);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('BBB','STA1','2',TO_DATE('01.07.2003','dd.mm.yyyy'),5);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('BBB','STA1','2',TO_DATE('01.07.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('BBB','STA1','2',TO_DATE('01.07.2003','dd.mm.yyyy'),12);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('BBB','STA3','2',TO_DATE('01.02.2003','dd.mm.yyyy'),1);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('BBB','STA3','2',TO_DATE('01.02.2003','dd.mm.yyyy'),5);
INSERT INTO COL_TABLE(COL1,COL2,COL3,COL4,COL5) VALUES('BBB','STA3','2',TO_DATE('01.02.2003','dd.mm.yyyy'),1);
I'd like to perform a mask displaying data based on the following SELECT-statement:
SELECT col1, col2, ok, bad,
ok/total*100 ok_percent, bad/total*100 bad_percent
FROM
(SELECT col1, col2,
SUM(DECODE(col5, 1, 1, 0)) ok,
SUM(DECODE(col5, 1, 0, 1)) bad,
count(*) total
FROM col_table
WHERE col4 BETWEEN TO_DATE('01.02.2003','dd.mm.yyyy') AND TO_DATE('01.07.2003','dd.mm.yyyy')
GROUP BY col1, col2);
The WHERE-clause should be implemented as two forms-text-items for example
start_date and end_date. If start_date and end_date are NULL,
there should be no date-range restriction (no WHERE-clause)
for the SELECT-statement.
My first thought was to create a view based on the SELECT-statement (without the WHERE-clause), because I do not know how to build the view "dynamically" with the date-ranges.
So I think building the mask based directly on the SELECT-statement would be fine.
Maybe there are other possibilities two solve this problem ??
Please help
|
|
|
Re: forms-mask based on stored procedure ? [message #85231 is a reply to message #85213] |
Thu, 10 June 2004 03:17 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
Tak Tang
Messages: 142 Registered: May 2004
|
Senior Member |
|
|
hudo,
In future posts, please mention which verion of forms you are using.
What is a 'forms-mask'?
You talk about two different cases for the WHERE clause. In forms 6i, you can set the WHERE clause at runtime using SET_BLOCK_PROPERTY.
Tak
|
|
|
Re: forms-mask based on stored procedure ? [message #85236 is a reply to message #85231] |
Thu, 10 June 2004 06:50 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
hudo
Messages: 165 Registered: May 2004
|
Senior Member |
|
|
I used forms 6i. But the masks should be displayed in a normal browser (in conjunction with the Oracle Application Server 10g). So you (Tak) told me that I have to "migrate". That's what I have done. I'm using at the moment both forms 6i and forms 9.0.4.0.19 (from the developer suite 10g)
With forms 9.0.4. I got same difficulties, for example the size of the displayed forms-mask (I call a forms-mask, a mask created with forms displaying the contents of a table for example the scott.emp table, in some way, or what I originally asked in this thread, a mask displaying the result of a SELECT-statement), or attaching a customer menue, although the Forms90Path is set and case-sensitivity is respected.
Back to my problem: I experimented with the example from the forms 6i online help, but I do not get along.
This example is:
/*
This is an example of a stored procedure that returns a ref cursor as a block datasource. A package is used to logically group the related data types and procedures.
*/
PACKAGE cv_datasource IS
TYPE emprec is RECORD (empno emp.empno%TYPE,
ename emp.ename%TYPE,
job emp.job%TYPE,
mgr emp.mgr%TYPE,
sal emp.sal%TYPE,
comm emp.comm%TYPE,
deptno emp.deptno%TYPE);
TYPE empcur is REF CURSOR RETURN emprec;
PROCEDURE empquery(resultset IN OUT empcur,
p_deptno IN NUMBER);
END;
PACKAGE BODY cv_datasource IS
PROCEDURE empquery(resultset IN OUT empcur,
p_deptno IN NUMBER) IS;
BEGIN
OPEN resultset FOR
SELECT empno, ename, job, mgr, sal, comm, deptno
FROM emp
WHERE deptno = p_deptno
ORDER BY empno;
END;
END;
When I start with the Data Block Wizard and choose Stored Procedure, then as Procedure-Name for the query:
cv_datasource.empquery ?, then choose all columns ? and
then there also the fields for entering values for the RESULTSET (Type REFCURSOR) and for P_DEPTNO (Type NUMBER) . What do I have to enter there ?? Continuing with the wizard he asks for an insert-procedure, a delete-procedure and so on. Can someone explain this a little bit more ? It would be great if the explanation would be even with my original example from the top of this thread.
Thanks for your help.
|
|
|
Re: forms-mask based on stored procedure ? [message #85239 is a reply to message #85236] |
Thu, 10 June 2004 09:24 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
Tak Tang
Messages: 142 Registered: May 2004
|
Senior Member |
|
|
In forms 6i, you can base a block on a select statement. You need to create the block manually; set the data source to 'from clause', and in the 'FROM' box, enter a SELECT statement in brackets.
eg (select ename, length(ename) as ename_length from emp)
This would give you two fields - ename and ename_length.
To implement the varying WHERE clause, I would use SET_BLOCK_PROPERTY just before executing the query, or maybe have a static where clause with NVL() to deal with a blank date range.
For basing a block on a REF CURSOR, I'll try to explain why Forms is asking for procedures. Normally, Forms creates blocks based on database tables, and automatically provides functionality to insert, update and delete records. A REF CURSOR however, can not be updated - you cannot issue DML against a ref cursor. So forms expects you to create procedures which do inserts, updates and deletes.
Here is a sample I got from a book :-
CREATE OR REPLACE
PACKAGE empdept_maint
AS
/******************************************************************************
|| System: SPMTS
||
|| Description:
|| Procedures used for an EMP-DEPT block query source and target.
||
|| Usage:
|| SLCT
|| Queries all records from the EMP-DEPT table join
||
|| INS
|| Inserts a record in the EMP-DEPT table.
||
|| UPD
|| Updates a record as specified by the empno parameter passed in.
||
|| DEL
|| Deletes the record specified by the empno parametere passed in.
||
|| LCK
|| Locks the record specified by the empno parametere passed in.
||
******************************************************************************/
TYPE emp_t IS RECORD(
empno emp.empno%TYPE,
job emp.job%TYPE,
hiredate emp.hiredate%TYPE,
deptno dept.deptno%TYPE,
dname dept.dname%TYPE);
-- For SELECT
TYPE rc_empdept IS REF CURSOR
RETURN emp_t;
-- For the DML - a table of records
TYPE t_empdept
IS TABLE OF emp_t
INDEX BY BINARY_INTEGER;
--
PROCEDURE slct(
p_empqry IN OUT rc_empdept);
--
PROCEDURE ins(
p_emprec IN OUT t_empdept);
--
PROCEDURE upd(
p_emprec IN OUT t_empdept);
--
PROCEDURE del(
p_emprec IN OUT t_empdept);
--
PROCEDURE lck(
p_emprec IN OUT t_empdept);
--
END;
/
CREATE OR REPLACE
PACKAGE BODY empdept_maint
AS
/*
|| Private procedures
*/
FUNCTION dept_not_exists(
p_dept_num NUMBER)
RETURN BOOLEAN
IS
CURSOR c_dept (
p_dept dept.deptno%TYPE)
IS
SELECT 1
FROM dept
WHERE deptno = p_dept;
--
v_dummy dept.deptno%TYPE;
v_return BOOLEAN;
BEGIN
OPEN c_dept(p_dept_num);
FETCH c_dept INTO v_dummy;
v_return := c_dept%NOTFOUND;
CLOSE c_dept;
RETURN v_return;
END;
/*
|| Public procedures
*/
PROCEDURE slct(
p_empqry IN OUT rc_empdept)
IS
BEGIN
-- This can be more complex and include conditional
-- logic to select from one source or another.
OPEN p_empqry
FOR
SELECT emp.empno,
emp.job,
emp.hiredate,
emp.deptno,
dept.dname
FROM emp emp, dept dept
WHERE emp.deptno = dept.deptno;
END;
--
--
PROCEDURE ins(
p_emprec IN OUT t_empdept)
IS
v_message VARCHAR2(100);
BEGIN
FOR v_ct IN 1 .. p_emprec.count
LOOP
-- If the dept doesn't exist, insert it
IF p_emprec(v_ct).deptno IS NOT NULL
THEN
IF dept_not_exists(p_emprec(v_ct).deptno)
THEN
v_message:= 'Insert of DEPT';
INSERT INTO dept(
deptno,
dname)
VALUES (p_emprec(v_ct).deptno,
p_emprec(v_ct).dname);
-- exception handling goes here. This might even be a separate
-- procedure to do the insert.
--
END IF;
--
v_message := 'Insert of EMP';
INSERT INTO emp(
empno,
job,
hiredate,
deptno)
VALUES (
p_emprec(v_ct).empno,
p_emprec(v_ct).job,
p_emprec(v_ct).hiredate,
p_emprec(v_ct).deptno);
-- add an exception handler here
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
raise_application_error(-20002, 'Error: Inserting record using ' ||
'EMPDEPT_MAINT.INS. Inform Technical Support. '|| v_message);
END;
--
--
PROCEDURE upd(
p_emprec IN OUT t_empdept)
IS
v_message VARCHAR2(200);
BEGIN
-- update the records from the table of records
-- check the dept table first
-- You could also update the DEPT record with the values
-- in the DEPT columns
-- For this exercise, just update the EMP columns
FOR v_ct IN 1 .. p_emprec.count
LOOP
IF dept_not_exists(p_emprec(v_ct).deptno)
THEN
v_message:= 'Insert of DEPT';
INSERT INTO dept(
deptno,
dname)
VALUES (p_emprec(v_ct).deptno,
p_emprec(v_ct).dname);
-- exception handling goes here. This might even be a separate
-- procedure to do the insert.
--
END IF;
--
UPDATE emp
SET job = p_emprec(v_ct).job,
hiredate = p_emprec(v_ct).hiredate,
deptno = p_emprec(v_ct).deptno
WHERE empno = p_emprec(v_ct).empno;
END LOOP;
END;
--
--
PROCEDURE del(
p_emprec IN OUT t_empdept)
IS
BEGIN
FOR v_ct IN 1 .. p_emprec.count
LOOP
DELETE FROM emp
WHERE empno = p_emprec(v_ct).empno;
END LOOP;
END;
PROCEDURE lck(
p_emprec IN OUT t_empdept)
IS
v_empno emp.empno%TYPE;
BEGIN
FOR v_ct IN 1 .. p_emprec.count
LOOP
SELECT empno
INTO v_empno
FROM emp
WHERE empno = p_emprec(v_ct).empno
FOR UPDATE;
END LOOP;
END;
END;
/
You can down load this, and other code from :-
http://ourworld.compuserve.com/homepages/Peter_Koletzke/Utilities/advdev.zip
|
|
|
Re: forms-mask based on stored procedure ? [message #85259 is a reply to message #85239] |
Fri, 11 June 2004 05:45 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
hudo
Messages: 165 Registered: May 2004
|
Senior Member |
|
|
@Tak: Thanks for the example, it works. I also implemented a "negative" example containing just the empdept_maint.slct procedure, then inserting or updating the table is not possible.
But I got some problems with the following:
-----
In forms 6i, you can base a block on a select statement. You need to create the block manually; set the data source to 'from clause', and in the 'FROM' box, enter a SELECT statement in brackets.
eg (select ename, length(ename) as ename_length from emp)
This would give you two fields - ename and ename_length.
To implement the varying WHERE clause, I would use SET_BLOCK_PROPERTY just before executing the query, or maybe have a static where clause with NVL() to deal with a blank date range.
----
I "Build a new data block manually". On the Block-Level Property-Palette:
Database->Database Data Block: Yes
Database->Query Data Source Type: FROM clause query
Database->Query Data Source Name: (select ename, length(ename) as ename_length from emp)
Then I build the two text items:
ENAME :
DATA->DataType: Char
Database->Database Item : ????
Database->Column Name: ???
ENAME_LENGTH :
Data->DataType:Number
Database->Database Item : ????
Database->Column Name: ???
By starting a query in Forms an error occurs:
FRM-41003: This function cannot by performed here
(because I tried to perform a function referencing a table, but the block does not correspond to any table)
Please help
|
|
|
Re: forms-mask based on stored procedure ? [message #85263 is a reply to message #85259] |
Fri, 11 June 2004 13:27 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
Tak Tang
Messages: 142 Registered: May 2004
|
Senior Member |
|
|
Consider this :-
CREATE VIEW emp_v AS
SELECT ename, LENGTH(ename) AS ename_length
FROM emp
/
You could select from this view, just as if it was a table.
SELECT v.ename, v.ename_length
FROM emp_v v
ORDER BY v.ename
/
Or I could write the view 'inline' like this :-
SELECT v.ename, v.ename_length
FROM ( SELECT ename, LENGTH(ename) AS ename_length FROM emp ) v
ORDER BY v.ename
/
You could also create a database block based on emp_v, exactly as if it was a table, or you could write the view 'inline'.
Does this explain enough for you to answer your own question?
Tak
|
|
|
Re: forms-mask based on stored procedure ? [message #85265 is a reply to message #85259] |
Fri, 11 June 2004 14:42 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
hudo
Messages: 165 Registered: May 2004
|
Senior Member |
|
|
No, not really. This was not my question.
Actually my problem is the IMPLEMENTATION of a query that is not based on a table nor a view but directly on a FROM-clause query (as you mentioned somewhere in this thread and is also indicated in the forms online-help).
Consider "its not allowed" for the developer to create views or even tables on the server, so he can query a stored procedure or use a FROM-clause query. But with the implementation of the last I got my problems:
I "Build a new data block manually". On the Block-Level Property-Palette:
Database->Database Data Block: Yes
Database->Query Data Source Type: FROM clause query
Database->Query Data Source Name: (select ename, length(ename) as ename_length from emp)
Database->Query Database Source Columns:
ENAME with Type VARCHAR2 and Length 10
ENAME_LENGTH with Type Number and Precision 2
Is this correct so far ??
Then I build the two text items:
NAME :
Data->DataType: Char
Database->Database Item : Yes
Database->Column Name: ENAME
LENG :
Data->DataType:Number
Database->Database Item : Yes
Database->Column Name: ENAME_LENGTH
Correct ??
But by starting a query in Forms an error occurs:
FRM-41003: This function cannot by performed here
Thanks for your advice and patience
|
|
|
Re: forms-mask based on stored procedure ? [message #178363 is a reply to message #85239] |
Tue, 20 June 2006 16:25 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) |
zsiddiquis
Messages: 4 Registered: June 2006 Location: Mississauga Canada
|
Junior Member |
|
|
Hi Gurus,
Eveything is going fine with this package but i found some problem whenever i update the and commit record then i wanted to execute query but form is stuck.
Any help will be appreciate.
Regards
Zeeshan
CREATE OR REPLACE PACKAGE empdept_maint
AS
-- Purpose :
--
-- Created By : Zeeshan Hussain Siddiqui
-- Creation Date : 20-06-2006
-- Last Updated BY : Zeeshan Hussain Siddiqui
-- Last Updataed On : 20-06-2006
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
TYPE emp_t IS RECORD(
empno emp.empno%TYPE,
job emp.job%TYPE,
hiredate emp.hiredate%TYPE,
deptno dept.deptno%TYPE,
dname dept.dname%TYPE);
-- For SELECT
TYPE rc_empdept IS REF CURSOR
RETURN emp_t;
-- For the DML - a table of records
TYPE t_empdept
IS TABLE OF emp_t
INDEX BY BINARY_INTEGER;
--
PROCEDURE slct(
p_empqry IN OUT rc_empdept);
FUNCTION dept_not_exists(p_dept_num NUMBER)
RETURN BOOLEAN;
--
PROCEDURE ins(
p_emprec IN OUT t_empdept);
--
PROCEDURE upd(
p_emprec IN OUT t_empdept);
--
PROCEDURE lck(
p_emprec IN OUT t_empdept);
PROCEDURE del(
p_emprec IN OUT t_empdept);
--
--
END empdept_maint;
/
CREATE OR REPLACE PACKAGE BODY empdept_maint
AS
-- Purpose :
--
-- Created By : Zeeshan Hussain Siddiqui
-- Creation Date : 20-06-2006
-- Last Updated BY : Zeeshan Hussain Siddiqui
-- Last Updataed On : 20-06-2006
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
PROCEDURE slct(
p_empqry IN OUT rc_empdept)
IS
BEGIN
-- This can be more complex and include conditional
-- logic to select from one source or another.
OPEN p_empqry
FOR
SELECT emp.empno,
emp.job,
emp.hiredate,
emp.deptno,
dept.dname
FROM emp emp, dept dept
WHERE emp.deptno = dept.deptno;
END slct;
-----------------------------------------------------------------------
FUNCTION dept_not_exists(
p_dept_num NUMBER)
RETURN BOOLEAN
IS
CURSOR c_dept (
p_dept dept.deptno%TYPE)
IS
SELECT 1
FROM dept
WHERE deptno = p_dept;
--
v_dummy dept.deptno%TYPE;
v_return BOOLEAN;
BEGIN
OPEN c_dept(p_dept_num);
FETCH c_dept INTO v_dummy;
v_return := c_dept%notfound;
CLOSE c_dept;
RETURN v_return;
END dept_not_exists;
-----------------------------------------------------------------------
PROCEDURE ins(
p_emprec IN OUT t_empdept)
IS
v_message VARCHAR2(100);
BEGIN
FOR v_ct IN 1 .. p_emprec.count
LOOP
-- If the dept doesn't exist, insert it
IF p_emprec(v_ct).deptno IS NOT NULL
THEN
IF dept_not_exists(p_emprec(v_ct).deptno)
THEN
v_message:= 'Insert of DEPT';
INSERT INTO dept(
deptno,
dname)
VALUES (p_emprec(v_ct).deptno,
p_emprec(v_ct).dname);
-- Exception handling goes here.
END IF;
--
v_message := 'Insert of EMP';
INSERT INTO emp(
empno,
job,
hiredate,
deptno)
VALUES (
p_emprec(v_ct).empno,
p_emprec(v_ct).job,
p_emprec(v_ct).hiredate,
p_emprec(v_ct).deptno);
-- add an exception handler here
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
raise_application_error(-20002, 'Error: Inserting record ' ||
'using EMPDEPT_MAINT.INS. Inform Technical Support. '|| v_message);
END ins;
----------------------------------------------------------------------------------------------
PROCEDURE upd(
p_emprec IN OUT t_empdept)
IS
v_message VARCHAR2(200);
BEGIN
-- update the records from the table of records
-- check the dept table first
-- You could also update the DEPT record with the values
-- in the DEPT columns
-- For this exercise, just update the EMP columns
FOR v_ct IN 1 .. p_emprec.count
LOOP
IF dept_not_exists(p_emprec(v_ct).deptno)
THEN
v_message:= 'Insert of DEPT';
INSERT INTO dept(
deptno,
dname)
VALUES (p_emprec(v_ct).deptno,
p_emprec(v_ct).dname);
-- exception handling goes here. This might even be a separate
-- procedure to do the insert.
--
END IF;
--
UPDATE emp
SET job = p_emprec(v_ct).job,
hiredate = p_emprec(v_ct).hiredate,
deptno = p_emprec(v_ct).deptno
WHERE empno = p_emprec(v_ct).empno;
END LOOP;
END upd;
----------------------------------------------------------------------------------------------
PROCEDURE lck(
p_emprec IN OUT t_empdept)
IS
v_empno emp.empno%TYPE;
BEGIN
FOR v_ct IN 1 .. p_emprec.count
LOOP
SELECT empno
INTO v_empno
FROM emp
WHERE empno = p_emprec(v_ct).empno
FOR UPDATE;
END LOOP;
END lck;
----------------------------------------------------------------------------------------------
PROCEDURE del(
p_emprec IN OUT t_empdept)
IS
BEGIN
FOR v_ct IN 1 .. p_emprec.count
LOOP
DELETE FROM emp
WHERE empno = p_emprec(v_ct).empno;
END LOOP;
END del;
END empdept_maint ;
/
|
|
|
Goto Forum:
Current Time: Sat Feb 08 13:25:48 CST 2025
|