Copying Responsibility in oracle ebs - plsql

user 'a' has 10 responsibilities in oracle EBS and user 'b' has 2 , i want to copy the remaining 8 responsibilities from user 'a' to 'b' using Pl/Sql procedure, how to do that. I tried the following code but it didn't compare the already common responsibility.
DECLARE
--
resp_count NUMBER := 0;
--
CURSOR src_user_resp_details
IS
SELECT DISTINCT fa.application_short_name,
fr.responsibility_key ,
fsg.security_group_key
FROM fnd_application fa ,
fnd_responsibility fr ,
fnd_user fu ,
fnd_user_resp_groups_all furga,
fnd_security_groups fsg
WHERE 1 = 1
AND fu.user_name = 'XX_ORACLE_APPS_DNA_1'
AND fu.user_id = furga.user_id
AND fa.application_id = fr.application_id
AND furga.responsibility_id = fr.responsibility_id
AND furga.responsibility_application_id = fa.application_id
AND fsg.security_group_id = furga.security_group_id
-- AND furga.end_date IS NULL OR trunc(furga.end_date) > trunc(SYSDATE)
AND furga.end_date IS NULL;
--
--
BEGIN
FOR user_resp_details_rec IN src_user_resp_details
LOOP
BEGIN
--
fnd_user_pkg.addresp
(username => 'XX_ORACLE_APPS_DNA_2',
resp_app => user_resp_details_rec.application_short_name,
resp_key => user_resp_details_rec.responsibility_key,
security_group => user_resp_details_rec.security_group_key,
description => NULL,
start_date => SYSDATE,
end_date => NULL
);
--
resp_count := resp_count + 1;
--
EXCEPTION
WHEN OTHERS THEN
--
DBMS_OUTPUT.put_line ( 'Error while Adding Responsibility: ' || SQLERRM );
DBMS_OUTPUT.put_line ( 'resp_app: ' || user_resp_details_rec.application_short_name );
DBMS_OUTPUT.put_line ( 'resp_key: ' || user_resp_details_rec.responsibility_key );
--
END;
END LOOP;
--
DBMS_OUTPUT.put_line (resp_count || ' Responsibilities Successfully Copied!!' );
--
COMMIT;
END;

The idea here is to exclude the already existin responsiblities in the Cursor only and pass those to the calling Procedure in the begin construct. Hope this helps.
DECLARE
--
resp_count NUMBER := 0;
--
CURSOR src_user_resp_details
IS
SELECT DISTINCT fa.application_short_name,
fr.responsibility_key ,
fsg.security_group_key
FROM fnd_application fa ,
fnd_responsibility fr ,
fnd_user fu ,
fnd_user_resp_groups_all furga,
fnd_security_groups fsg
WHERE 1 = 1
AND fu.user_name = 'XX_ORACLE_APPS_DNA_1'
AND fu.user_id = furga.user_id
AND fa.application_id = fr.application_id
AND furga.responsibility_id = fr.responsibility_id
AND furga.responsibility_application_id = fa.application_id
AND fsg.security_group_id = furga.security_group_id
-- AND furga.end_date IS NULL OR trunc(furga.end_date) > trunc(SYSDATE)
AND FURGA.END_DATE IS NULL
AND furga.responsibility_id NOT IN --Exclude those resposibilites which are already there in User 2. Only those resp whoch are present in 1 but not in 2
(SELECT RESPONSIBILITY_ID
FROM FND_APPLICATION FA2 ,
FND_RESPONSIBILITY FR2 ,
FND_USER FU2 ,
FND_USER_RESP_GROUPS_ALL FURGA2,
fnd_security_groups fsg2
WHERE 1 = 1
AND FU2.USER_NAME = 'XX_ORACLE_APPS_DNA_2'
AND FU2.USER_ID = FURGA2.USER_ID
AND FA2.APPLICATION_ID = FR2.APPLICATION_ID
AND FURGA2.RESPONSIBILITY_ID = FR2.RESPONSIBILITY_ID
AND FURGA2.RESPONSIBILITY_APPLICATION_ID = FA2.APPLICATION_ID
AND fsg2.security_group_id = furga2.security_group_id
-- AND furga.end_date IS NULL OR trunc(furga.end_date) > trunc(SYSDATE)
AND FURGA2.END_DATE IS NULL
);
--
--
BEGIN
FOR user_resp_details_rec IN src_user_resp_details
LOOP
BEGIN
--
FND_USER_PKG.ADDRESP (USERNAME => 'XX_ORACLE_APPS_DNA_2',
RESP_APP => USER_RESP_DETAILS_REC.APPLICATION_SHORT_NAME,
RESP_KEY => USER_RESP_DETAILS_REC.RESPONSIBILITY_KEY,
SECURITY_GROUP => USER_RESP_DETAILS_REC.SECURITY_GROUP_KEY,
DESCRIPTION => null,
start_date => SYSDATE,
end_date => NULL );
--
resp_count := resp_count + 1;
--
EXCEPTION
WHEN OTHERS THEN
--
DBMS_OUTPUT.put_line ( 'Error while Adding Responsibility: ' || SQLERRM );
DBMS_OUTPUT.put_line ( 'resp_app: ' || user_resp_details_rec.application_short_name );
DBMS_OUTPUT.put_line ( 'resp_key: ' || user_resp_details_rec.responsibility_key );
--
END;
END LOOP;
--
DBMS_OUTPUT.put_line (resp_count || ' Responsibilities Successfully Copied!!' );
--
COMMIT;
END;

Related

PLSQL : Return Concatenated string of all attributes of a Object

--Declare Object
create or replace TYPE INP_OBJ AS OBJECT
( attribute_1 VARCHAR2(20 CHAR)
,attribute_2 VARCHAR2(20 CHAR)
);
--Create Package
CREATE OR REPLACE PACKAGE TEST AS
PROCEDURE PROC1 (l_inp_obj IN INP_OBJ) ;
END TEST;
--Create Package Body
create or replace PACKAGE BODY TEST AS
PROCEDURE PROC1 (l_inp_obj IN INP_OBJ) IS
BEGIN
dbms_output.put_line(l_inp_obj.attribute_1 || ' ~ '|| l_inp_obj.attribute_2);
-- have to write every element individually here
END PROC1;
END TEST;
-- Calling Procedure
DECLARE
L_INP_OBJ INP_OBJ;
BEGIN
L_INP_OBJ := (INP_OBJ('VALUE OF ATTR 1'
,'VALUE OF ATTR 2'));
TEST.PROC1(L_INP_OBJ => L_INP_OBJ);
END;
for display I had to write every attribute of input object individually. Is there a better way to return concatenated string of all values of Input Object ?
From my answer to this similar question, you can write a package:
CREATE PACKAGE reflection IS
TYPE type_info IS RECORD(
prec PLS_INTEGER,
scale PLS_INTEGER,
len PLS_INTEGER,
csid PLS_INTEGER,
csfrm PLS_INTEGER,
schema_name VARCHAR2(30),
type_name VARCHAR2(30),
version VARCHAR2(100),
count PLS_INTEGER
);
TYPE attr_info IS RECORD(
prec PLS_INTEGER,
scale PLS_INTEGER,
len PLS_INTEGER,
csid PLS_INTEGER,
csfrm PLS_INTEGER,
attr_elt_type ANYTYPE,
aname VARCHAR2(30)
);
FUNCTION get_size(
p_anydata IN ANYDATA
) RETURN PLS_INTEGER;
FUNCTION get_attr_name_at(
p_anydata IN ANYDATA,
p_index IN PLS_INTEGER DEFAULT 1
) RETURN VARCHAR2;
FUNCTION get_attr_value_at(
p_anydata IN ANYDATA,
p_index IN PLS_INTEGER DEFAULT 1
) RETURN VARCHAR2;
END;
/
With the body:
CREATE PACKAGE BODY reflection IS
DEBUG BOOLEAN := FALSE;
FUNCTION get_type(
p_anydata IN ANYDATA
) RETURN ANYTYPE
IS
v_typeid PLS_INTEGER;
v_anytype ANYTYPE;
v_type_info REFLECTION.TYPE_INFO;
BEGIN
v_typeid := p_anydata.GetType( typ => v_anytype );
RETURN v_anytype;
END;
FUNCTION get_info(
p_anytype IN ANYTYPE
) RETURN type_info
IS
v_typeid PLS_INTEGER;
v_type_info REFLECTION.TYPE_INFO;
BEGIN
v_typeid := p_anytype.GetInfo (
v_type_info.prec,
v_type_info.scale,
v_type_info.len,
v_type_info.csid,
v_type_info.csfrm,
v_type_info.schema_name,
v_type_info.type_name,
v_type_info.version,
v_type_info.count
);
IF v_typeid <> DBMS_TYPES.TYPECODE_OBJECT THEN
RAISE_APPLICATION_ERROR( -20000, 'Not an object.' );
END IF;
RETURN v_type_info;
END;
FUNCTION get_size(
p_anydata IN ANYDATA
) RETURN PLS_INTEGER
IS
BEGIN
RETURN Get_Info( Get_Type( p_anydata ) ).COUNT;
END;
FUNCTION get_attr_name_at(
p_anydata IN ANYDATA,
p_index IN PLS_INTEGER DEFAULT 1
) RETURN VARCHAR2
IS
v_anydata ANYDATA := p_anydata;
v_anytype ANYTYPE;
v_type_info REFLECTION.TYPE_INFO;
v_output VARCHAR2(4000);
v_attr_typeid PLS_INTEGER;
v_attr_info REFLECTION.ATTR_INFO;
BEGIN
v_anytype := Get_Type( v_anydata );
v_type_info := Get_Info( v_anytype );
IF p_index < 1 OR p_index > v_type_info.COUNT THEN
RETURN NULL;
END IF;
v_anydata.PIECEWISE;
v_attr_typeid := v_anytype.getAttrElemInfo(
pos => p_index,
prec => v_attr_info.prec,
scale => v_attr_info.scale,
len => v_attr_info.len,
csid => v_attr_info.csid,
csfrm => v_attr_info.csfrm,
attr_elt_type => v_attr_info.attr_elt_type,
aname => v_attr_info.aname
);
RETURN v_attr_info.aname;
END;
FUNCTION get_attr_value_at(
p_anydata IN ANYDATA,
p_index IN PLS_INTEGER DEFAULT 1
) RETURN VARCHAR2
IS
v_anydata ANYDATA := p_anydata;
v_anytype ANYTYPE;
v_type_info REFLECTION.TYPE_INFO;
v_output VARCHAR2(4000);
BEGIN
v_anytype := Get_Type( v_anydata );
v_type_info := Get_Info( v_anytype );
IF p_index < 1 OR p_index > v_type_info.COUNT THEN
RETURN NULL;
END IF;
v_anydata.PIECEWISE;
FOR i IN 1 .. p_index LOOP
DECLARE
v_attr_typeid PLS_INTEGER;
v_attr_info REFLECTION.ATTR_INFO;
v_result_code PLS_INTEGER;
BEGIN
v_attr_typeid := v_anytype.getAttrElemInfo(
pos => i,
prec => v_attr_info.prec,
scale => v_attr_info.scale,
len => v_attr_info.len,
csid => v_attr_info.csid,
csfrm => v_attr_info.csfrm,
attr_elt_type => v_attr_info.attr_elt_type,
aname => v_attr_info.aname
);
IF DEBUG THEN
DBMS_OUTPUT.PUT_LINE(
'Attribute ' || i || ': '
|| v_attr_info.aname
|| ' (type ' || v_attr_typeid || ')'
);
END IF;
CASE v_attr_typeid
WHEN DBMS_TYPES.TYPECODE_NUMBER THEN
DECLARE
v_value NUMBER;
BEGIN
v_result_code := v_anydata.GetNumber( v_value );
IF i = p_index THEN
RETURN TO_CHAR( v_value );
END IF;
END;
WHEN DBMS_TYPES.TYPECODE_VARCHAR2 THEN
DECLARE
v_value VARCHAR2(4000);
BEGIN
v_result_code := v_anydata.GetVarchar2( v_value );
IF i = p_index THEN
RETURN v_value;
END IF;
END;
WHEN DBMS_TYPES.TYPECODE_DATE THEN
DECLARE
v_value DATE;
BEGIN
v_result_code := v_anydata.GetDate( v_value );
IF i = p_index THEN
RETURN TO_CHAR( v_value, 'YYYY-MM-DD HH24:MI:SS' );
END IF;
END;
ELSE
NULL;
END CASE;
END;
END LOOP;
RETURN NULL;
END;
END;
/
Then you can iterate over the object to find the attributes and write the package as:
CREATE PACKAGE TEST AS
PROCEDURE PROC1 (p_anydata IN ANYDATA);
END TEST;
/
CREATE PACKAGE BODY TEST AS
PROCEDURE PROC1 (p_anydata IN ANYDATA)
IS
p_attr_name VARCHAR2(30);
p_attr_value VARCHAR2(4000);
BEGIN
FOR attr_no IN 1 .. REFLECTION.get_size(p_anydata) LOOP
p_attr_name := REFLECTION.get_attr_name_at(p_anydata, attr_no);
p_attr_value := REFLECTION.get_attr_value_at(p_anydata, attr_no);
IF attr_no > 1 THEN
DBMS_OUTPUT.PUT( ' ~ ' );
END IF;
DBMS_OUTPUT.PUT( p_attr_value );
END LOOP;
DBMS_OUTPUT.NEW_LINE;
END PROC1;
END TEST;
/
Then call it using:
DECLARE
L_INP_OBJ INP_OBJ;
BEGIN
L_INP_OBJ := INP_OBJ('VALUE OF ATTR 1' ,'VALUE OF ATTR 2');
TEST.PROC1(P_ANYDATA => ANYDATA.ConvertObject(L_INP_OBJ);
END;
/

CREATE OR REPLACE PROCEDURE proc_video_search

Create a procedure called proc_video_search to search for a video and display the name, copy ID, format, and status of the video’s copies. In addition, the checkout dates and due dates are also displayed for unreturned copies. The damaged copies (Status = 'D') are excluded in your output. Sort your output by the video name (Name) and then the copy ID (CopyID).
$ CREATE OR REPLACE PROCEDURE proc_video_search (
p_VideoName VARCHAR2,
p_FormatName VARCHAR2 DEFAULT NULL) as
v_Count NUMBER;
v_TotalCopies NUMBER; v_Avalb NUMBER;v_FormatName VARCHAR2(100);
v_VideoName VARCHAR2(100); v_CopyID VARCHAR2(100);v_DueDate DATE;
v_Status VARCHAR2(100); v_CheckoutDate DATE;
CURSOR asdf IS
SELECT T_VIDEO.Name, T_COPY.CopyID, Status,T_VIDEO_FORMAT.NAME
FROM T_VIDEO
INNER JOIN T_COPY ON T_VIDEO.VideoID = T_COPY.VideoID
INNER JOIN T_VIDEO_FORMAT ON T_VIDEO_FORMAT.FormatID =
T_VIDEO.FormatID
WHERE Status !='D' AND UPPER(T_VIDEO.Name) like '%' ||
UPPER(p_VideoName) || '%'
OR UPPER(T_VIDEO_FORMAT.NAME)= UPPER(p_FormatName)
ORDER BY T_VIDEO.Name, T_COPY.CopyID;
BEGIN
SELECT COUNT(*)
INTO v_Count
FROM T_VIDEO
WHERE UPPER(T_VIDEO.Name) like '%' || UPPER(p_VideoName) || '%' ;
IF v_count = 0 THEN
DBMS_OUTPUT.PUT_LINE('**** '||v_Count|| ' results found for ' ||
p_VideoName||'. *****');
RETURN;
END IF;
SELECT count(T_COPY.CopyID) INTO v_TotalCopies
FROM T_COPY INNER JOIN T_VIDEO ON T_COPY.VideoID = T_VIDEO.VideoID
INNER JOIN T_VIDEO_FORMA ON T_VIDEO_FORMAT.FormatID =
T_VIDEO.FormatID
WHERE Status !='D' AND UPPER(T_VIDEO.Name) like '%' ||
UPPER(p_VideoName) ||'%'
OR UPPER(T_VIDEO_FORMAT.NAME)=UPPER(p_FormatName);
SELECT count(T_COPY.CopyID)INTO v_Avalb FROM T_COPY
INNER JOIN T_VIDEO ON T_COPY.VideoID = T_VIDEO.VideoID
INNER JOIN T_VIDEO_FORMAT ON T_VIDEO_FORMAT.FormatID =
T_VIDEO.FormatID
WHERE Status ='A' AND UPPER(T_VIDEO.Name) like '%' ||
UPPER(p_VideoName) ||'%'
OR UPPER(T_VIDEO_FORMAT.NAME)=UPPER(p_FormatName);
IF v_TotalCopies >=0 THEN
IF p_FormatName IS NULL THEN
DBMS_OUTPUT.PUT_LINE(v_TotalCopies||' results found for '||
p_VideoName||' . (Available copies:'|| v_Avalb|| ')' );
ELSE
DBMS_OUTPUT.PUT_LINE(v_TotalCopies||' results found for '||
p_VideoName||'('|| p_FormatName||') . (Available copies:'||
v_Avalb|| ')' );
end if;
OPEN asdf;
LOOP
FETCH asdf INTO v_VideoName, v_CopyID, v_Status,
v_FormatName ; exit when asdf%NOTFOUND ;
SELECT COUNT(CheckoutDate)
INTO v_Count FROM T_RENTAL WHERE CopyID = v_CopyID;
IF v_Count = 1 THEN
SELECT CheckoutDate,DueDate
INTO v_CheckoutDate,v_DueDate
FROM T_RENTAL
WHERE CopyID = v_CopyID;
end if;
DBMS_OUTPUT.PUT_LINE(RPAD('-', 53, '-'));
DBMS_OUTPUT.PUT_LINE(RPAD('Name:',30) || RPAD(v_VideoName,15));
DBMS_OUTPUT.PUT_LINE(RPAD('CopyID:',30) || RPAD(v_CopyID,15));
DBMS_OUTPUT.PUT_LINE(RPAD('Format:',30) ||
RPAD(v_FormatName,15));
IF v_Status = 'A' THEN v_Status := 'Available';END IF;
IF v_Status = 'R' THEN v_Status := 'Rented'; END IF;
DBMS_OUTPUT.PUT_LINE(RPAD('Status:',30) || RPAD(v_Status,15));
IF v_Status ='Available' THEN
DBMS_OUTPUT.PUT_LINE(RPAD('CheckoutDate:',30)
||'****************************');
DBMS_OUTPUT.PUT_LINE(RPAD('DueDate:',30)
||'****************************');
ELSE
DBMS_OUTPUT.PUT_LINE(RPAD('CheckoutDate:',30)
||RPAD(TO_CHAR(v_CheckoutDate, 'DD-MON-YYYY'),15));
DBMS_OUTPUT.PUT_LINE(RPAD('DueDate:',30) ||RPAD(TO_CHAR(
v_DueDate, 'DD-MON-YYYY'),15));
END IF; END LOOP; CLOSE asdf; END IF; END proc_video_search ;
EXEC proc_video_search('ANOTHER', 'DVD')`
enter image description here
The problem is with this line of your cursor asdf
OR UPPER(T_VIDEO_FORMAT.NAME)= UPPER(p_FormatName)
Because it says OR, the query can choose to ignore this criteria if it evaluates to false. That is why you are getting results with all the formats; it ignores the filtering.
You have to wrap the OR statement in another AND clause, like so
WHERE Status !='D'
AND UPPER(T_VIDEO.Name) like '%' || UPPER(p_VideoName) || '%'
AND ( /* OR clause here */ )
And then you can handle the case of p_formatName being null or not.

update query with OR condition in PL/sql

I have a update query in PL/SQL where I need to use OR condition based on itemsetid='XXXX or orgid ='YYYYY' this is because not all tables have these 2 fields so I need to use OR condition. I tried as below but it's not working ,
set serveroutput on size unlimited ;
declare
type item_type
is record (
maxSameas maxattribute.sameasattribute%TYPE,
maxTable maxattribute.objectname%TYPE,
maxAttrib maxattribute.attributename%TYPE
);
Type attribArray is table of item_type;
allAttribs attribArray;
cursor ITEM_ATTRIB_CURSOR is
select a.sameasattribute, a.objectname, a.attributename
from maxattribute a, maxobject b
where a.persistent = 1
and a.objectname = b.objectname
and b.persistent = 1
and ((a.sameasattribute is not null
and a.sameasattribute like 'ITEMNUM')
or (a.attributename = 'ITEMNUM'))
and a.objectname <> 'ITEMHIST'
-- and a.objectname <> 'ITEM'
and b.isView = '0'
order by a.objectname asc, a.attributename asc, a.sameasattribute desc;
type itemXrefType
is record (
currValue itemhist.ITEMNUM%type,
oldValue itemhist.OLDITEMNUM%type
);
type itemXrefTable is table of itemXrefType;
itemXref itemXrefTable;
cursor ITEM_VAL_CURSOR is
select itemnum, olditemnum
from itemhist
where olditemnum is not null and itemsetid='XXXXX';
updateStr varchar2 (4000);
queryStr varchar2 (4000);
tableName varchar2 (30);
attribName varchar2(50);
rowKount NUMBER;
begin
DBMS_OUTPUT.ENABLE(NULL);
-- Fetch Cross Reference Data
open item_val_cursor;
fetch item_val_cursor bulk collect into itemXref;
close item_val_cursor;
-- Fetch all Objects with ITEMNUM attribute
open ITEM_ATTRIB_CURSOR;
fetch ITEM_ATTRIB_CURSOR bulk collect into allAttribs;
close ITEM_ATTRIB_CURSOR;
-- Loop through every Object
for i in allAttribs.first..allAttribs.last loop
tableName := allAttribs(i).maxTable;
if (tableName = 'ITEM') then
attribName := 'ITEMNUM';
else
attribName := allAttribs(i).maxAttrib;
end if;
for j in itemXref.first .. itemXref.last loop
-- For each Item Num, update all objects
queryStr := 'select count (1) from ' || tableName ||
' where ' || attribName || '=' || '''' || itemXref(j).oldValue || '''';
-- Get Count before update
EXECUTE IMMEDIATE queryStr into RowKount;
updateStr := 'update ' || tableName ||
' set ' || attribName || ' = ' || '''' || itemXref(j).currValue
|| ''' where ' || attribName || '=' || '''' || itemXref(j).oldValue || ''' and (itemsetid = ''' || 'XXXX' || ''' or orgid = ''' || 'YYYYY' || ''' ) ''' '''';
--dbms_output.put_line (itemXref(j).currValue || ' ::::' || itemXref(j).oldValue);
dbms_output.put_line (updateStr || ':: Records to be updated is ' || rowKount);
-- Execute the Update
EXECUTE IMMEDIATE updateStr;
-- Commit changes
updateStr := 'Commit';
EXECUTE IMMEDIATE updateStr;
-- Get count after update - should be none!
EXECUTE IMMEDIATE queryStr into RowKount;
dbms_output.put_line (' Count of records after the update is ' || rowKount);
end loop;
end loop; --for i in allAttribs
end;
Thanks in advance!

Looping with If condition in PL/SQL

I created this block to test three conditions from a table called process. I created the sql query based on the requirements and I inserted it into a FOR LOOP that should return more than a value every time I test a date which matches the date in the process table. My problems with this block is -First: When I test invalid date against the DATE_PO records, I get the ELSE condition, but this starts to loop twice for the number of records in the table process:
anonymous block completed
No records made in this date !
No records made in this date !
The second problem, if no data in this table, how do I make an appropriate condition to test and display a message to the user of no records found?
Table process
NUM DATE_PO STATUS
---------- ----------- -----------
1243 21-DEC-15 CANCEL
5678 21-DEC-15 APPROVE
BEGIN
FOR X IN
(SELECT PO.STATUS,
PO.DATE_PO,
SUM(D.QUANTIY) QUANTITY_SUM,
SUM(NVL(D.QUANTIY,0) * NVL (M.COST,0)) T_VALUE
FROM PROCESS.PO, DELETE_PROCESS, MONEY M
WHERE D.PO = M.PO
AND PO.NUM = D.NUM
GROUP BY PO.STATUS, PO.DATE_PO)
LOOP
IF TO_CHAR(X.DATE_PO, 'mm-yyyy') ='10-2015' THEN --Not valid date
IF X.STATUS ='CANCEL' THEN
DBMS_OUTPUT.PUT_LINE('CANCELLATIONS: ' || X.QUANTITY_SUM );
DBMS_OUTPUT.PUT_LINE('VALUE: '|| X.T_VALUE);
DBMS_OUTPUT.PUT_LINE('DATE: ' || X.DATE_PO );
ELSIF X.STATUS ='HOLD' THEN
DBMS_OUTPUT.PUT_LINE('HOLDS: ' || X.QUANTITY_SUM );
DBMS_OUTPUT.PUT_LINE('VALUE: '|| X.T_VALUE);
DBMS_OUTPUT.PUT_LINE('DATE: ' || X.DATE_PO );
ELSIF X.STATUS = 'APPROVE' THEN
DBMS_OUTPUT.PUT_LINE('APPROVES: ' || X.QUANTITY_SUM );
DBMS_OUTPUT.PUT_LINE('VALUE: '|| X.T_VALUE);
DBMS_OUTPUT.PUT_LINE('DATE: ' || X.DATE_PO );
END IF;
ELSE
DBMS_OUTPUT.PUT_LINE('No records made in this date !');
END IF;
END LOOP;
END;
/
Try this. Hope it helps. Though its not the best solution as it can be
done without using ROW-BY-ROW processing. Bulk COLLECT option can also
be used. Let me know if this helps. Since i dont have workspace please
pardon any syntax erros if any.
DECLARE
lv_cnt PLS_INTEGER;
lv_date VARCHAR2(10):='12-2015';
lv_dt DATE;
BEGIN
BEGIN
SELECT TO_DATE(lv_date,'MM-YYYY') INTO lv_dt FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Not a valid Date');
RETURN;
END;
SELECT COUNT(1)
INTO lv_cnt
FROM
(SELECT PO.STATUS,
PO.DATE_PO,
SUM(D.QUANTIY) QUANTITY_SUM,
SUM(NVL(D.QUANTIY,0) * NVL (M.COST,0)) T_VALUE
FROM PROCESS.PO,
DELETE_PROCESS,
MONEY M
WHERE D.PO = M.PO
AND PO.NUM = D.NUM
GROUP BY PO.STATUS,
PO.DATE_PO
)A;
IF lv_cnt > 0 THEN
FOR X IN
(SELECT PO.STATUS,
PO.DATE_PO,
SUM(D.QUANTIY) QUANTITY_SUM,
SUM(NVL(D.QUANTIY,0) * NVL (M.COST,0)) T_VALUE
FROM PROCESS.PO,
DELETE_PROCESS,
MONEY M
WHERE D.PO = M.PO
AND PO.NUM = D.NUM
GROUP BY PO.STATUS,
PO.DATE_PO
)
LOOP
IF X.STATUS ='CANCEL' THEN
DBMS_OUTPUT.PUT_LINE('CANCELLATIONS: ' || X.QUANTITY_SUM );
DBMS_OUTPUT.PUT_LINE('VALUE: '|| X.T_VALUE);
DBMS_OUTPUT.PUT_LINE('DATE: ' || X.DATE_PO );
ELSIF X.STATUS ='HOLD' THEN
DBMS_OUTPUT.PUT_LINE('HOLDS: ' || X.QUANTITY_SUM );
DBMS_OUTPUT.PUT_LINE('VALUE: '|| X.T_VALUE);
DBMS_OUTPUT.PUT_LINE('DATE: ' || X.DATE_PO );
ELSIF X.STATUS = 'APPROVE' THEN
DBMS_OUTPUT.PUT_LINE('APPROVES: ' || X.QUANTITY_SUM );
DBMS_OUTPUT.PUT_LINE('VALUE: '|| X.T_VALUE);
DBMS_OUTPUT.PUT_LINE('DATE: ' || X.DATE_PO );
END IF;
END LOOP;
ELSIF lv_cnt = 0 THEN
dbms_output.put_line('No records found for the user');
END IF;
END;

SYS.DBMS_DDL.WRAP not allowing pragma and intctx

I am using the below procedure to wrap the PL/SQL Code.
declare
l_source DBMS_SQL.VARCHAR2A;
l_wrap DBMS_SQL.VARCHAR2A;
l_wrap1 clob;
typ_ibt utl_file.file_type;
cnt number := 0;
v_directory varchar2(400) := 'd:\ftpedi\eqpm\eqpm_hold\';
cursor cur_name_get is
select distinct name object_name,type object_type
from user_source
where type = 'PROCEDURE'
and name = 'PROCESS_TIME_INSERT';
cursor cut_text_get ( p_type in varchar2 , p_name in varchar2 ) is
select replace(text,chr(10),'') text
from user_source
where type = p_type
and name = p_name;
begin
for i in cur_name_get
loop
l_source.delete;l_wrap.delete;
open cut_text_get ( i.object_type,i.object_name );
fetch cut_text_get bulk collect into l_source;
close cut_text_get;
l_source (1) := 'CREATE OR REPLACE ' || l_source (1);
l_wrap := SYS.DBMS_DDL.WRAP(ddl => l_source,
lb => 1,
ub => l_source.count);
for i in 1..l_wrap.count
loop
if i = 1
then
l_wrap1 := l_wrap(i);
else
l_wrap1 := l_wrap1 || l_wrap(i);
end if;
insert into ibt_global_inter_transfer ( git_process_id,git_c_1)
values ( 3004, l_wrap1 );
end loop;
end loop;
exception when others
then
dbms_output.put_line('sqlerrm '||sqlerrm||dbms_utility.format_error_backtrace);
end;
The above procedures warps the normal procedure, but not allowing the special character like 'PRAGMA'.
The below is the sample procedure, which is not wrapping.
CREATE OR REPLACE
PROCEDURE xml_insert ( p_in_xml in xmltype ,p_status out varchar2,p_message out varchar2) is
intctx DBMS_XMLSTORE.ctxtype;
rows number;
begin
p_status := 'S';
p_message := 'Success';
intctx := Dbms_xmlstore.newcontext('IBT_GLOBAL_INTER_TRANSFER');
dbms_xmlstore.clearupdatecolumnlist(intctx);
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_PROCESS_ID');
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_SESSION_ID');
rows := Dbms_xmlstore.insertxml(intctx,p_in_xml);
dbms_xmlstore.closecontext(intctx);
exception when others
then
p_status := 'R';
p_message := sqlerrm||dbms_utility.format_error_backtrace;
return;
end;
Could anyone help?
Update
(I misunderstood the problem. I thought you meant the wrapped code wasn't created, now I understand the real problem is that the wrapped output does not compile.)
Remove the replace, there needs to be white space between some of the lines.
Replace:
--select replace(text,chr(10),'') text
with:
select text
Procedure:
CREATE OR REPLACE
PROCEDURE xml_insert ( p_in_xml in xmltype ,p_status out varchar2,p_message out varchar2) is
intctx DBMS_XMLSTORE.ctxtype;
rows number;
pragma autonomous_transaction; --ADDED
begin
p_status := 'S';
p_message := 'Success';
intctx := Dbms_xmlstore.newcontext('IBT_GLOBAL_INTER_TRANSFER');
dbms_xmlstore.clearupdatecolumnlist(intctx);
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_PROCESS_ID');
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_SESSION_ID');
rows := Dbms_xmlstore.insertxml(intctx,p_in_xml);
dbms_xmlstore.closecontext(intctx);
exception when others
then
p_status := 'R';
p_message := sqlerrm||dbms_utility.format_error_backtrace;
return;
end;
/
PL/SQL Block wrapping code:
declare
l_source DBMS_SQL.VARCHAR2A;
l_wrap DBMS_SQL.VARCHAR2A;
l_wrap1 clob;
typ_ibt utl_file.file_type;
cnt number := 0;
v_directory varchar2(400) := 'd:\ftpedi\eqpm\eqpm_hold\';
cursor cur_name_get is
select distinct name object_name,type object_type
from user_source
where type = 'PROCEDURE'
and name = 'XML_INSERT'; --CHANGED
cursor cut_text_get ( p_type in varchar2 , p_name in varchar2 ) is
--select replace(text,chr(10),'') text --WOOPS!
select text
from user_source
where type = p_type
and name = p_name;
begin
for i in cur_name_get
loop
l_source.delete;l_wrap.delete;
open cut_text_get ( i.object_type,i.object_name );
fetch cut_text_get bulk collect into l_source;
close cut_text_get;
l_source (1) := 'CREATE OR REPLACE ' || l_source (1);
l_wrap := SYS.DBMS_DDL.WRAP(ddl => l_source,
lb => 1,
ub => l_source.count);
for i in 1..l_wrap.count
loop
if i = 1
then
l_wrap1 := l_wrap(i);
else
l_wrap1 := l_wrap1 || l_wrap(i);
end if;
--insert into ibt_global_inter_transfer ( git_process_id,git_c_1)
--values ( 3004, l_wrap1 );
dbms_output.put_line(l_wrap1);
end loop;
end loop;
exception when others
then
dbms_output.put_line('sqlerrm '||sqlerrm||dbms_utility.format_error_backtrace);
end;
/

Resources