Looping in stored procedure
Hi,
I have a query like this,
select email as vEmail from users where id in (217211,217521,217641)
Now this query returns 3 email id's. I have to loop through the vEmail and assign them to different local variables in stored procedures.
like email for 217211 is stored in vEmail1
217521 in vEmail2
217641 in vEmail3
Can somehow help me in this looping?
Hi,
Do you really need them in 3 separate variables, like vemail1, vemail2 and vemail3?
Would you be just as happy if they were in 3 separate members of a collection: vemail(1), vemal(2) and vemail(3)? If so, use BULK COLLECT. It will be a lot more efficient (though, if you're only fetching 3 rows, that won't amount to much).
The PL/SQL manual has a nice example:
http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/tuning.htm#sthref1474
Similar Messages
-
Can someone explain to me how I loop a stored procedure ?
I have a stored proc that deletes users. it works fine.
set serveroutput on
begin
BTNEP.DEL_USERPROC (p_employee_id=>'11111');
end;
I have a list of over 1,000 employee_id's that need to be deleted.
Is there a way i can loop through this list using the procedure ?
thanks for any helpok so i put in table.
i tried
BEGIN
FOR i IN (SELECT employee_id FROM employee_USERIDS)
LOOP
BTNEP.DEL_USERPROC (p_employee_id => i.employee_id);
END LOOP;
END;
Error starting at line 1 in command:
BEGIN
FOR i IN (SELECT employee_id FROM employee_USERIDS)
LOOP
BTNEP.DEL_USERPROC (p_employee_id => i.employee_id);
END LOOP;
END;
Error report:
ORA-06550: line 4, column 7:
PLS-00201: identifier 'BTNEP.DEL_USERPROC' must be declared
ORA-06550: line 4, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action: -
Hello
I'm hoping that someone here might be able to help or point me in the right direction. Apologies for the long post.
Just to set the scene, I am a SQL Server DBA and have very limited experience with System Centre so please go easy on me.
At the company I am currently working they are complaining about very poor performance when running reports (any).
Quick look at the database server and CPU utilisation being a constant 90-95%, meant that you dont have to be Sherlock Holmes to realise there is a problem. The instance consuming the majority of the CPU is the instance hosting the datawarehouse and in particular
a stored procedure in the DWStagingAndConfig database called Staging.GroomDwStagingData.
This stored procedure executes continually for 2 hours performing 500,000,000 reads per execution before "timing out". It is then executed again for another 2 hours etc etc.
After a bit of diagnosis it seems that the issue is either a bug or that there is something wrong with our data in that a stored procedure is stuck in an infinite loop
System Center 2012 SP1 CU2 (5.0.7804.1300)
Diagnosis details
SQL connection details
program name = SC DAL--GroomingWriteModule
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
Store procedures executed
1. dbo.p_GetDwStagingGroomingConfig (executes immediately)
2. Staging.GroomDwStagingData (this is the procedure that executes in 2 hours before being cancelled)
The 1st stored procedure seems to return a table with the "xml" / required parameters to execute Staging.GroomDwStagingData
Sample xml below (cut right down)
<Config>
<Target>
<ModuleName>TransformActivityDim</ModuleName>
<WarehouseEntityName>ActivityDim</WarehouseEntityName>
<RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName>
<Watermark>2015-01-30T08:59:14.397</Watermark>
</Target>
<Target>
<ModuleName>TransformActivityDim</ModuleName>
<WarehouseEntityName>ActivityDim</WarehouseEntityName>
<RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName>
<ManagedTypeViewName>MTV_Microsoft$SystemCenter$Orchestrator$RunbookAutomationActivity</ManagedTypeViewName>
<Watermark>2015-01-30T08:59:14.397</Watermark>
</Target>
</Config>
If you look carefully you will see that the 1st <target> is missing the ManagedTypeViewName, which when "shredded" by the Staging.GroomDwStagingData returns the following result set
Example
DECLARE @Config xml
DECLARE @GroomingCriteria NVARCHAR(MAX)
SET @GroomingCriteria = '<Config><Target><ModuleName>TransformActivityDim</ModuleName><WarehouseEntityName>ActivityDim</WarehouseEntityName><RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName><Watermark>2015-01-30T08:59:14.397</Watermark></Target><Target><ModuleName>TransformActivityDim</ModuleName><WarehouseEntityName>ActivityDim</WarehouseEntityName><RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName><ManagedTypeViewName>MTV_Microsoft$SystemCenter$Orchestrator$RunbookAutomationActivity</ManagedTypeViewName><Watermark>2015-01-30T08:59:14.397</Watermark></Target></Config>'
SET @Config = CONVERT(xml, @GroomingCriteria)
SELECT
ModuleName = p.value(N'child::ModuleName[1]', N'nvarchar(255)')
,WarehouseEntityName = p.value(N'child::WarehouseEntityName[1]', N'nvarchar(255)')
,RequiredWarehouseEntityName =p.value(N'child::RequiredWarehouseEntityName[1]', N'nvarchar(255)')
,ManagedTypeViewName = p.value(N'child::ManagedTypeViewName[1]', N'nvarchar(255)')
,Watermark = p.value(N'child::Watermark[1]', N'datetime')
FROM @Config.nodes(N'/Config/*') Elem(p)
/* RESULTS - NOTE THE NULL VALUE FOR ManagedTypeViewName
ModuleName WarehouseEntityName RequiredWarehouseEntityName ManagedTypeViewName Watermark
TransformActivityDim ActivityDim MTV_System$WorkItem$Activity NULL 2015-01-30 08:59:14.397
TransformActivityDim ActivityDim MTV_System$WorkItem$Activity MTV_Microsoft$SystemCenter$Orchestrator$RunbookAutomationActivity 2015-01-30 08:59:14.397
When the procedure enters the loop to build its dynamic SQL to delete relevant rows from the inbound schema tables it concatenates various options / variables into an executable string. However when adding a NULL value to a string the entire string becomes
NULL which then gets executed.
Whilst executing "EXEC(NULL)" would cause SQL to throw an error and be caught, executing the following doesnt
DECLARE @null_string VARCHAR(100)
SET @null_string = 'hello world ' + NULL
EXEC(@null_string)
SELECT @null_string
So as it hasnt caused an error the next part of the procedure is to move to the next record and this is why its caught in an infinite loop
DELETE @items WHERE ManagedTypeViewName = @View
The value for the variable @View is the ManagedTypeViewName which is NULL, as ANSI_NULLS are set to ON in the connection and not overridded in the procedure then the above statement wont delete anything as it needs to handle NULL values differently (IS NULL),
so we are now stuck in an infinite loop executing NULL for 2 hours until cancelled.
I amended the stored procedure and added the following line before the loop statement which had the desired effect and "fixed" the performance issue for the time being
DELETE @items WHERE ManagedTypeViewName IS NULL
I also noticed that the following line in dbo.p_GetDwStagingGroomingConfig is commented out (no idea why as no notes in the procedure)
--AND COALESCE(i.ManagedTypeViewName, j.RelationshipTypeViewName) IS NOT NULL
There are obviously other ways to mitigate the dynamic SQL string being NULL, there's more than one way to skin a cat and thats not why I am asking this question, but what I am concerned about is that is there a reason that the xml / @GroomingCriteria is incomplete
and / or that the procedures dont handle potential NULL values.
I cant find any documentation, KBs, forum posts of anyone else having this issue which somewhat surprises me.
Would be grateful of any help / advice that anyone can provide or if someone can look at their 2 stored procedures on a later version to see if it has already been fixed. Or is it simply that we have orphaned data, this is the bit that concerns most as I dont
really want to be deleting / updating data when I have no idea what the knock on effect might be
Many many thanks
AndyFirst thing I would do is upgrade to 2012 R2 UR5. If you are running non-US dates you need the UR5 hotfix also.
Rob Ford scsmnz.net
Cireson www.cireson.com
For a free SCSM 2012 Notify Analyst app click
here -
Trying to pass array to stored procedure in a loop using bind variable
All,
I'm having trouble figuring out if I can do the following:
I have a stored procedure as follows:
create procedure enque_f826_utility_q (inpayload IN f826_utility_payload, msgid out RAW) is
enqopt dbms_aq.enqueue_options_t;
mprop dbms_aq.message_properties_t;
begin
dbms_aq.enqueue(queue_name=>'f826_utility_queue',
enqueue_options=>enqopt,
message_properties=>mprop,
payload=>inpayload,
msgid=>msgid);
end;
The above compiles cleanly.
The first parameter "inpayload" a database type something like the following:
create or replace type f826_utility_payload as object
2 (
3 YEAR NUMBER(4,0),
4 MONTH NUMBER(2,0),
83 MUSTHAVE CHAR(1)
84 );
I'd like to call the stored procedure enque_f826_utility_q in a loop passing to it
each time, new values in the inpayload parameter.
My questions are:
First, I'm not sure in php, how to construct the first parameter which is a database type.
Can I just make an associative array variable with the keys of the array the same as the columns of the database type shown above and then pass that array to the stored procedure?
Second, is it possible to parse a statement that calls the enque_f826_utility_q procedure using bind variables and then execute the call to the stored procedure in a loop passing new bind variables each time?
I've tried something like the following but it's not working:
$conn = oci_pconnect (....);
$stmt = "select * from f826_utility";
$stid = oci_parse($conn, $sqlstmt);
$r = oci_execute($stid, OCI_DEFAULT);
$row = array();
$msgid = "";
$enqstmt = "call enque_f826_utility_q(:RID,:MID)";
$enqstid = oci_parse($conn, $sqlstmt);
oci_bind_by_name($enqstid, ":RID", $row); /* line 57 */
oci_bind_by_name($enqstid, ":MID", $msgid);
while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS+OCI_ASSOC))
++$rowcnt;
if (! oci_execute($enqstid)) /* line 65 */
echo "Error";
exit;
When I run this, I get the following:
PHP Notice: Array to string conversion in C:\Temp\enqueue_f826_utility.php on l
ine 57
Entering loop to process records from F826_UTIITY table
PHP Notice: Array to string conversion in C:\Temp\enqueue_f826_utility.php on l
ine 65
PHP Warning: oci_execute(): ORA-06553: PLS-306: wrong number or types of argume
nts in call to 'ENQUE_F826_UTILITY_Q' in C:\Temp\enqueue_f826_utility.php on lin
e 65
PHP Notice: Undefined variable: msgnum in C:\Temp\enqueue_f826_utility.php on l
ine 68
Error during oci_execute of statement select * from F826_UTILITY
Exiting!Thanks for the reply.
I took a look at this article. What it appears to describe is
a calling a stored procedure that takes a collection type which is an array.
Does anyone from Oracle know if I can pass other database type definitions to a stored procedure from PHP?
I have a type defined in my database similar to the following which is not
an array but a record of various fields. This type corresponds to a payload
of an advanced queue payload type. I have a stored procedure which will take as it's input, a payload type of this structure and then enqueue it to a queue.
So I want to be able to pass a database type similar to the following type definition from within PHP. Can anyone from Oracle verify whether or not this is possible?
create or replace type f826_utility_payload as object
YEAR NUMBER(4,0),
MONTH NUMBER(2,0),
UTILITY_ID NUMBER(10,0),
SUBMIT_FAIL_BY VARCHAR2(30),
MUSTHAVE CHAR(1)
); -
How to use equals in loop of an Stored Procedure
Hi ,
This is my Stored Procedure which is working fine (mean displaying all the Data from the Table)
Here i want to add this functionality that is i want to check if there is 'IND' in country_code , i want to throw an Exception manually .
I am struck up here : After the cursor fetches all the country_code in its loop , how can i check the whether country_code contains 'IND' or not in it ??
create or replace PROCEDURE Auto_After_Bod_Status
is
country_code VARCHAR2(40);
myException EXCEPTION ;
CURSOR PD1
IS
SELECT COUNTRY_CODE FROM LINK_STATUS;
BEGIN
OPEN PD1;
LOOP
FETCH PD1 INTO country_code;
DBMS_OUTPUT.PUT_LINE(country_code);
EXIT WHEN PD1%NOTFOUND;
END LOOP;
CLOSE PD1;
END Auto_After_Bod_Status;
please help .Thanks .user10503747 wrote:
I am struck up here : After the cursor fetches all the country_code in its loop , how can i check the whether country_code contains 'IND' or not in it ??Why do you need to check it after the loop. Check as soon as row is fetched. Also, your DBMS_OUTPUT.PUT_LINE(country_code); should be after EXIT WHEN PD1%NOTFOUND; not before:
create or replace PROCEDURE Auto_After_Bod_Status
is
country_code VARCHAR2(40);
myException EXCEPTION ;
CURSOR PD1
IS
SELECT COUNTRY_CODE FROM LINK_STATUS;
BEGIN
OPEN PD1;
LOOP
FETCH PD1 INTO country_code;
EXIT WHEN PD1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(country_code);
IF country_code LIKE '%IND%'
THEN close pd1;
raise myException;
END IF;
END LOOP;
CLOSE PD1;
END Auto_After_Bod_Status;But if you want to fetch all rows first:
create or replace PROCEDURE Auto_After_Bod_Status
is
country_code VARCHAR2(40);
ind number := 0;
myException EXCEPTION ;
CURSOR PD1
IS
SELECT COUNTRY_CODE FROM LINK_STATUS;
BEGIN
OPEN PD1;
LOOP
FETCH PD1 INTO country_code;
EXIT WHEN PD1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(country_code);
IF country_code LIKE '%IND%'
THEN ind := 1;
END IF;
END LOOP;
CLOSE PD1;
IF ind = 1
THEN raise myException;
END IF;
END Auto_After_Bod_Status;SY. -
Unable to get the data from the stored procedure
Hello Folks,
I have this stored procedure and am trying to get the data from the table stage_bill but for some reason i am not sure its not pulling the data.Am a beginner in pl/sql Can any one please help to find out. I can give the code below.
create or replace procedure Load_FADM_Staging_Area_TEST(p_data_load_date date) is
-- local variables
v_start_date date;
v_end_date date;
-- cursor starting
CURSOR c_get_data
IS
SELECT
a.batch_id
,a.beginning_service_date
,a.bill_id
,a.bill_method
,a.bill_number
,a.bill_received_date
,a.bill_status
,a.bill_type
,a.change_oltp_by
,a.change_oltp_date
,a.client_datafeed_code
,a.client_id
,a.created_date
,a.date_of_incident
,a.date_paid
,a.deleted_oltp_by
,a.deleted_oltp_date
,a.duplicate_bill
,a.ending_service_date
,a.event_case_id
,a.event_id
,a.from_oltp_by
,a.oltp_bill_status
,a.review_status
,'HRI' schema_name
, sysdate Load_date
,'ETLPROCESS001' Load_user
,v_start_date as Row_Effective_Date
,null Row_End_date
from stage_bill a
where
--created_date >= to_date('20101031 235959', 'YYYYMMDD HH24MISS')
created_date >= v_start_date
and
--created_date <= to_date('20101111 235959', 'YYYYMMDD HH24MISS')
created_date <= v_end_date
and not exists
(select
b.batch_id
,b.beginning_service_date
,b.bill_id
,b.bill_method
,b.bill_number
,b.bill_received_date
,b.bill_status
,b.bill_type
,b.change_oltp_by
,b.change_oltp_date
,b.client_datafeed_code
,b.client_id
,b.created_date
,b.date_of_incident
,b.date_paid
,b.deleted_oltp_by
,b.deleted_oltp_date
,b.duplicate_bill
,b.ending_service_date
,b.event_case_id
,b.event_id
,b.from_oltp_by
,b.oltp_bill_status
,b.review_status,
b.schema_name,
b.Load_date,
b.Load_user,
b.Row_Effective_Date,
b.Row_End_Date
from STG_FADM_HRI_STAGE_BILL_TEST b)
-- cursor o/p variables
v_batch_id stage_bill.batch_id%TYPE;
v_beginning_service_date stage_bill.beginning_service_date%TYPE;
v_bill_id stage_bill.bill_id%TYPE;
v_bill_method stage_bill.bill_method%TYPE;
v_bill_number stage_bill.bill_number%TYPE;
v_bill_received_date stage_bill.bill_received_date%TYPE;
v_bill_status stage_bill.bill_status%TYPE;
v_bill_type stage_bill.bill_type%TYPE;
v_change_oltp_by stage_bill.change_oltp_by%TYPE;
v_change_oltp_date stage_bill.change_oltp_date%TYPE;
v_client_datafeed_code stage_bill.client_datafeed_code%TYPE;
v_client_id stage_bill.client_id%TYPE;
v_created_date stage_bill.created_date%TYPE;
v_date_of_incident stage_bill.date_of_incident%TYPE;
v_date_paid stage_bill.date_paid%TYPE;
v_deleted_oltp_by stage_bill.deleted_oltp_by%TYPE;
v_deleted_oltp_date stage_bill.deleted_oltp_date%TYPE;
v_duplicate_bill stage_bill.duplicate_bill%TYPE;
v_ending_service_date stage_bill.ending_service_date%TYPE;
v_event_case_id stage_bill.event_case_id%TYPE;
v_event_id stage_bill.event_id%TYPE;
v_from_oltp_by stage_bill.from_oltp_by%TYPE;
v_oltp_bill_status stage_bill.oltp_bill_status%TYPE;
v_review_status stage_bill.review_status%TYPE;
v_schema_name varchar(50);
v_Load_date date;
v_Load_user varchar(50);
v_Row_Effective_Date date;
v_Row_End_Date date;
Begin
if p_data_load_date is null then
select (sysdate - 7), (sysdate - 1) into v_start_date, v_end_date from dual;
elsif p_data_load_date is not null then
select (p_data_load_date - 7), (p_data_load_date - 1) into v_start_date, v_end_date from dual;
else
raise_application_error('-20042', 'Data control - GetDataControlAuditData : Date parameter must be a date of this or a previous week.');
end if;
-- cursor c_get_data loop begin
OPEN c_get_data;
LOOP -- cursor c_get_data loop begin
FETCH c_get_data
INTO
v_batch_id,
v_beginning_service_date,
v_bill_id ,
v_bill_method ,
v_bill_number,
v_bill_received_date,
v_bill_status,
v_bill_type,
v_change_oltp_by,
v_change_oltp_date,
v_client_datafeed_code,
v_client_id,
v_created_date,
v_date_of_incident,
v_date_paid,
v_deleted_oltp_by,
v_deleted_oltp_date,
v_duplicate_bill,
v_ending_service_date ,
v_event_case_id ,
v_event_id,
v_from_oltp_by,
v_oltp_bill_status,
v_review_status,
v_schema_name,
v_Load_date,
v_Load_user,
V_Row_Effective_Date,
v_Row_End_Date;
EXIT WHEN c_get_data%NOTFOUND;
insert into STG_FADM_HRI_STAGE_BILL_TEST
batch_id
,beginning_service_date
,bill_id
,bill_method
,bill_number
,bill_received_date
,bill_status
,bill_type
,change_oltp_by
,change_oltp_date
,client_datafeed_code
,client_id
,created_date
,date_of_incident
,date_paid
,deleted_oltp_by
,deleted_oltp_date
,duplicate_bill
,ending_service_date
,event_case_id
,event_id
,from_oltp_by
,oltp_bill_status
,review_status
,schema_name
,Load_date
,Load_user
,Row_Effective_Date
,Row_End_Date
values(
v_batch_id,
v_beginning_service_date,
v_bill_id ,
v_bill_method ,
v_bill_number,
v_bill_received_date,
v_bill_status,
v_bill_type,
v_change_oltp_by,
v_change_oltp_date,
v_client_datafeed_code,
v_client_id,
v_created_date,
v_date_of_incident,
v_date_paid,
v_deleted_oltp_by,
v_deleted_oltp_date,
v_duplicate_bill,
v_ending_service_date ,
v_event_case_id ,
v_event_id,
v_from_oltp_by,
v_oltp_bill_status,
v_review_status,
v_schema_name,
v_Load_date,
v_Load_user,
v_Row_Effective_Date,
v_Row_End_Date ) ;
COMMIT;
END LOOP;
CLOSE c_get_data;Maybe you need something else, like
CREATE OR REPLACE PROCEDURE load_fadm_staging_area_test (
p_data_load_date DATE
) IS
v_start_date DATE;
v_end_date DATE;
BEGIN
SELECT NVL (p_data_load_date, SYSDATE) - 7,
NVL (p_data_load_date, SYSDATE) - 1
INTO v_start_date,
v_end_date
FROM DUAL;
MERGE INTO stg_fadm_hri_stage_bill_test b
USING (SELECT *
FROM stage_bill
WHERE created_date BETWEEN v_start_date AND v_end_date) a
ON (b.bill_id = a.billl_id)
WHEN NOT MATCHED THEN
INSERT (batch_id,
beginning_service_date,
bill_id,
bill_method,
bill_number,
bill_received_date,
bill_status,
bill_type,
change_oltp_by,
change_oltp_date,
client_datafeed_code,
client_id,
created_date,
date_of_incident,
date_paid,
deleted_oltp_by,
deleted_oltp_date,
duplicate_bill,
ending_service_date,
event_case_id,
event_id,
from_oltp_by,
oltp_bill_status,
review_status,
schema_name,
load_date,
load_user,
row_effective_date,
row_end_date
VALUES (a.batch_id,
a.beginning_service_date,
a.bill_id,
a.bill_method,
a.bill_number,
a.bill_received_date,
a.bill_status,
a.bill_type,
a.change_oltp_by,
a.change_oltp_date,
a.client_datafeed_code,
a.client_id,
a.created_date,
a.date_of_incident,
a.date_paid,
a.deleted_oltp_by,
a.deleted_oltp_date,
a.duplicate_bill,
a.ending_service_date,
a.event_case_id,
a.event_id,
a.from_oltp_by,
a.oltp_bill_status,
a.review_status,
'HRI',
SYSDATE,
'ETLPROCESS001',
v_start_date,
NULL
END load_fadm_staging_area_test;Whenever you code a cursor and a loop, ask yourself. Do I need that?
Regards
Peter -
Cannot Send Email Notification Using Stored Procedure.
Hi Friends,
I tried to execute this job scheduler...
begin
dbms_scheduler.create_job(
job_name => 'ILMS_JOB_SCHEDULE'
,job_type => 'PLSQL_BLOCK'
,job_action => 'begin ilms.check_reminder(); end; '
,start_date => SYSTIMESTAMP
,repeat_interval => 'FREQ=DAILY'
,enabled => TRUE
,end_date => NULL
,comments => 'Ilms job schedule for notification.');
end;
However, since the effect is too long I rescheduled the frequency to be every one minute in this set attribute...
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => 'ILMS_JOB_SCHEDULE'
,attribute => 'repeat_interval'
,value => 'FREQ=MINUTELY;INTERVAL=1'
DBMS_SCHEDULER.DISABLE('ILMS_JOB_SCHEDULE');
DBMS_SCHEDULER.ENABLE('ILMS_JOB_SCHEDULE');
END;
Check Reminder is the stored procedure invoked by job scheduler to check values in database columns before sending email notification to the respective recipients' email address and also the format of the email notification to be sent to the recipients...
CREATE OR REPLACE PROCEDURE check_reminder AS
NO number;
CURSOR emp_cur is
select * from pergerakan_ks where TASK_FLAG=7 and TASK_STATUS='InProgress';
emp_rec emp_cur%rowtype;
email_to varchar2(200);
default_email varchar2(200);
mesg varchar2(4000);
no_kes varchar2(100);
subj varchar2(4000);
kpi number;
crlf VARCHAR2( 2 ):= CHR( 13 ) || CHR( 10 );
BEGIN
default_email:='@abc.com.my';
FOR emp_rec in emp_cur
LOOP
if emp_rec.PKS_TKH_TERIMA is null then
dbms_output.put_line('count day ' || round(sysdate - to_date(emp_rec.pks_tkh_hantar)) || crlf || crlf);
if round(sysdate - to_date(emp_rec.pks_tkh_hantar)) >3 then
email_to:=emp_rec.pks_penghantar_id||default_email;
select b.KS_BIL_NO into no_kes from kertas_siasatan b where b.KS_ID = emp_rec.pks_ks_id;
subj:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
mesg:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
dbms_output.put_line('Sending email to ' || email_to || ' subject: ' || subj);
dbms_output.put_line('update old pergerakan pks_id : '||emp_rec.pks_id);
update pergerakan_ks set task_status='Done' where pks_id=emp_rec.pks_id;
dbms_output.put_line('insert new pergerakan ks : ');
insert into pergerakan_ks(pks_id,pks_ks_id,pks_km_id,pks_penghantar_id,pks_tkh_hantar,
pks_penerima_id,pks_tkh_terima,task_name,task_owner,task_status,task_flag,fb_id)
values(pks_id_seq.nextval,emp_rec.pks_ks_id,emp_rec.pks_km_id,
emp_rec.pks_penghantar_id,sysdate,
null,
null,emp_rec.task_name,
emp_rec.pks_penghantar_id,
'InProgress',6,emp_rec.fb_id);
commit;
e_mail_message(email_to,email_to,subj,mesg);
end if;
end if;
if emp_rec.PKS_TKH_TERIMA is not null then
dbms_output.put_line('emp_rec.pks_km_id ' || emp_rec.pks_km_id || crlf);
select c.KM_KPI into kpi from keluar_masuk_ks c where c.KM_ID = emp_rec.pks_km_id;
no := round(sysdate - to_date(emp_rec.pks_tkh_terima))-kpi;
dbms_output.put_line('count day - kpi' || no || crlf);
dbms_output.put_line('kpi ' || kpi || crlf);
if no = 1 then
email_to:=emp_rec.pks_penghantar_id||default_email;
select b.KS_BIL_NO into no_kes from kertas_siasatan b where b.KS_ID = emp_rec.pks_ks_id;
subj:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
mesg:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
dbms_output.put_line('Sending email to ' || email_to || ' subject: ' || subj);
email_to:=emp_rec.task_owner||default_email;
subj:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
mesg:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
dbms_output.put_line('Sending email to ' || email_to || ' subject: ' || subj);
e_mail_message(email_to,email_to,subj,mesg);
e_mail_message(email_to,email_to,subj,mesg);
end if;
if no = 3 then
select b.KS_BIL_NO into no_kes from kertas_siasatan b where b.KS_ID = emp_rec.pks_ks_id;
email_to:=emp_rec.task_owner||default_email;
subj:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
mesg:='Reminder untuk Membuat Tindakan Bagi No Kes '||no_kes;
dbms_output.put_line('Sending email to ' || email_to || ' subject: ' || subj);
e_mail_message(email_to,email_to,subj,mesg);
end if;
end if;
END LOOP;
END;
E_mail_message is the stored procedure invoked by the check_reminder to tell scheduler information of the connection and the email address of the recipients...
CREATE OR REPLACE procedure
e_mail_message
from_name in varchar2,
to_name in varchar2,
subject in varchar2,
message in varchar2
is
l_mailhost VARCHAR2(64);
l_from VARCHAR2(64);
l_to VARCHAR2(64);
crlf VARCHAR2( 2 ):= CHR( 13 ) || CHR( 10 );
l_mail_conn UTL_SMTP.connection;
mesg VARCHAR2( 4000 );
BEGIN
select a.SERVER into l_mailhost from email_setting a where a.SERVER is not null;
select a.USERNAME into l_from from email_setting a where a.SERVER is not null;
--UTL_SMTP.open_data(l_mail_conn);
mesg:= 'Date: ' || TO_CHAR( SYSDATE, 'dd Mon yy hh24:mi:ss' ) || crlf ||
'From: <'||l_from||'>' || crlf ||
'Subject: ' ||subject|| crlf ||
'To: '||to_name || crlf || '' || crlf ;
mesg:=mesg||message;
l_mail_conn := UTL_SMTP.open_connection(l_mailhost, 25);
UTL_SMTP.helo(l_mail_conn, l_mailhost);
UTL_SMTP.mail(l_mail_conn, l_from);
UTL_SMTP.rcpt(l_mail_conn, to_name);
UTL_SMTP.data(l_mail_conn, mesg);
UTL_SMTP.quit(l_mail_conn);
END;
I tried to execute to execute the e_mail_message procedure but received this error. Also, no notification sent to the email address...
ORA-29279: SMTP permanent error: 501 5.1.3 Invalid address
ORA-06512: at "SYS.UTL_SMTP", line 21
ORA-06512: at "SYS.UTL_SMTP", line 99
ORA-06512: at "SYS.UTL_SMTP", line 241
ORA-06512: at "ILMS.E_MAIL_MESSAGE", line 33
ORA-06512: at line 13
Please help so that I can receive the email notification into my email...thanks in advance for your time..user13281540 wrote:
ORA-29279: SMTP permanent error: 501 5.1.3 Invalid address
ORA-06512: at "SYS.UTL_SMTP", line 21
ORA-06512: at "SYS.UTL_SMTP", line 99
ORA-06512: at "SYS.UTL_SMTP", line 241
ORA-06512: at "ILMS.E_MAIL_MESSAGE", line 33
ORA-06512: at line 13This is not an Oracle error - this is the mail server saying "+hey, I don't like that e-mail address you are supplying, I'm not accepting it!+".
If you look at RFC821 (Request For Comments memo 821 describes the SMTP specifications), you'll see that the sender and recipient needs to be supplied in the format +<[email protected]>+, e.g. +<[email protected]>+.
I have found that not all SMTP servers are equal in this regard. Some may insist on the brackets around the address, some may not.
You need to confirm the format of the addresses you use in the "+MAIL FROM+" and "+RCPT TO+" commands.. and ensure that these formats are accepted by your SMTP server - and if not, change your code to use an acceptable format.
The easiest way to do this is using telnet - and interacting directly and manually with the server. SMTP is a clear text protocol and easy to use manually. Try it. It is the best way to test SMTP interaction and validate the approach and SMTP commands and arguments used by your code. -
How can I check a Remote Database is alive in a Stored Procedure
Hi
In a PL/SQL stored procedure, I do a select from a table on a remote database via the database link. There is a Loop around the select as it waits for a flag to be set on the remote table. However, on several occasions, while looping, the remote database has gone down and the procedure then fails with error:
'Details ORA-02068: following severe error from ORA-02068: following severe error from 'Remote Database ' ORA-01033: ORACLE initialization or shutdown in progress ORA-06512: at "Current Database.Stored Procedure", line'
Is it possible to trap this error and prevent the procedure from crashing?
My current code is like:-
LOOP
SELECT flag
INTO v_flag
FROM remote_table@remote_db;
IF v_flag= 'OK'
THEN
< Run Oracle Warehouse Builder Process Flow >
EXIT;
ELSE dbms_lock.sleep(600);
END IF;
END LOOP;
Any help with this would be appreciated.
Thanks
GBHi Bernd
Thanks for your help. If I do this, I think the procedure would continue onto the 'IF' statement. I am looking for a way of looping round and trying to run the select again before moving on.
If I did something like
LOOP --- Loop 1 ---
LOOP --- Loop 2---
BEGIN
SELECT flag
INTO v_flag
FROM remote_table@remote_db;
EXCEPTION WHEN OTHERS THEN NULL;
END;
-- Need to exit if no exception ---
END LOOP;
IF v_flag= 'OK'
THEN
< Run Oracle Warehouse Builder Process Flow >
EXIT;
ELSE dbms_lock.sleep(600);
END IF;
END LOOP;
Is there a way of going back to the start of Loop 2 if there was an exception, otherwise EXIT and continue onto the 'IF' statement. -
Speed test: PL/SQL vs. Java Stored Procedures
I performed tests on these two procedures:
===========================================
// Create a Statement
Statement stmt = conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
// Query the table
ResultSet rset = stmt.executeQuery ("select SIFOB, SIFRA_GU from sezko");
while (rset.next ()) {
salary = rset.getInt(1);
rset.updateInt (1, salary + 1);
salary = rset.getInt(2);
rset.updateInt (2, salary + 1);
rset.updateRow();
} // while
conn.commit();
// Close the RseultSet
rset.close();
// Close the Statement
stmt.close();
===========================================
procedure updateTable is
cursor c_updateTable is select rowid, SIFOB, SIFRA_GU from sezko;
begin
for r_updateTable in c_updateTable loop
update sezko set SIFOB = SIFOB + 1, SIFRA_GU = SIFRA_GU + 1 where rowid = r_updateTable.rowid;
end loop;
commit;
end;
===========================================
First procedure is written in Java (as Java Stored procedure) and second is PL/SQL.
Java is about 10x slower than PL/SQL code.
Can you explain bad performance results?
thank you
Matic & AlesHi,
I suppose the problem is not with the connection object,but with make connection to the database for every executeupdate or executeupdaterow called .Similarly for fetching the data from the database you
can use the fetch size technique.Please check the 8.1.6 Java Developers guide for using this.
Update Batching(For Batch updates and commits)
Fetch Size(For Batch fetching)
Oracle Row Pre-Fetching
Regards
Anand
null -
How to add records or how to maintain list in stored Procedure
Hi,
I am facing an issue in the addition of record in the type
create or replace
TYPE "PROD_SEARCH_COUNT_TBL" AS TABLE OF PROD_SEARCH_COUNT_OBJ;
create or replace
TYPE "PROD_SEARCH_COUNT_OBJ" AS OBJECT
( /* TODO enter attribute and method declarations here */
V_Name Varchar2(500 Byte),
v_Value Varchar2(500 Byte),
v_count Number
I want to add records to the type I tried following way
prod_wcf_rec PROD_SEARCH_COUNT_TBL;
SELECT PROD_SEARCH_COUNT_OBJ('Name1','Value1',1) BULK COLLECT INTO prod_wcf_rec FROM DUAL;
SELECT PROD_SEARCH_COUNT_OBJ('Name2','Value2',2) BULK COLLECT INTO prod_wcf_rec FROM DUAL;
SELECT PROD_SEARCH_COUNT_OBJ('Name3','Value3',3) BULK COLLECT INTO prod_wcf_rec FROM DUAL;
SELECT PROD_SEARCH_COUNT_OBJ('Name4','Value4',4) BULK COLLECT INTO PROD_WCF_REC FROM DUAL;
DBMS_OUTPUT.PUT_LINE ('-----------------------------Looping----------------------------');
FOR i in 1 .. prod_wcf_rec.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE (prod_wcf_rec(i).V_Name||' - '||prod_wcf_rec(i).v_Value||' - '||prod_wcf_rec(i).v_count);
END LOOP;
DBMS_OUTPUT.PUT_LINE ('-----------------------------Looping----------------------------');
In printing I am getting last records only .So is there any way to add records to PROD_SEARCH_COUNT_TBL
How to add records or how to maintain list in stored ProcedureEvery time you BULK COLLECT into a collection type the value is overwirtten. So you need to try something like this.
SQL> create or replace type prod_search_count_obj as object(v_name varchar2(500 byte), v_value varchar2(500 byte), v_count number)
2 /
Type created.
SQL> create or replace type prod_search_count_tbl as table of prod_search_count_obj
2 /
Type created.
SQL> declare
2 prod_wcf_rec prod_search_count_tbl;
3 begin
4 select obj_val
5 bulk collect into prod_wcf_rec
6 from (
7 select prod_search_count_obj('name1','value1',1) obj_val from dual
8 union all
9 select prod_search_count_obj('name2','value2',2) from dual
10 union all
11 select prod_search_count_obj('name3','value3',3) from dual
12 union all
13 select prod_search_count_obj('name4','value4',4) from dual
14 );
15
16 dbms_output.put_line ('-----------------------------looping----------------------------');
17 for i in 1 .. prod_wcf_rec.count
18 loop
19 dbms_output.put_line (prod_wcf_rec(i).v_name||' - '||prod_wcf_rec(i).v_value||' - '||prod_wcf_rec(i).v_count);
20 end loop;
21 dbms_output.put_line ('-----------------------------looping----------------------------');
22 end;
23 /
-----------------------------looping----------------------------
name1 - value1 - 1
name2 - value2 - 2
name3 - value3 - 3
name4 - value4 - 4
-----------------------------looping----------------------------
PL/SQL procedure successfully completed.
SQL> -
How to get an updatable ADODB Recordset from a Stored Procedure?
In VB6 I have this code to get a disconnected ADODB Recordset from a Oracle 9i database (the Oracle Client is 10g):
Dim conSQL As ADODB.Connection
Dim comSQL As ADODB.Command
Dim recSQL As ADODB.Recordset
Set conSQL = New ADODB.Connection
With conSQL
.ConnectionString = "Provider=OraOLEDB.Oracle;Password=<pwd>;Persist Security Info=True;User ID=<uid>;Data Source=<dsn>"
.CursorLocation = adUseClientBatch
.Open
End With
Set comSQL = New ADODB.Command
With comSQL
.ActiveConnection = conSQL
.CommandType = adCmdStoredProc
.CommandText = "P_PARAM.GETALLPARAM"
.Properties("PLSQLRSet").Value = True
End With
Set recSQL = New ADODB.Recordset
With recSQL
Set .Source = comSQL
.CursorLocation = adUseClient
.CursorType = adOpenStatic
.LockType = adLockBatchOptimistic
.Open
.ActiveConnection = Nothing
End With
The PL/SQL Procedure is returning a REF CURSOR like this:
PROCEDURE GetAllParam(op_PARAMRecCur IN OUT P_PARAM.PARAMRecCur)
IS
BEGIN
OPEN op_PARAMRecCur FOR
SELECT *
FROM PARAM
ORDER BY ANNPARAM DESC;
END GetAllParam;
When I try to update some values in the ADODB Recordset (still disconnected), I get the following error:
Err.Description: Multiple-step operation generated errors. Check each status value.
Err.Number: -2147217887 (80040E21)
Err.Source: Microsoft Cursor Engine
The following properties on the Command object doesn't change anything:
.Properties("IRowsetChange") = True
.Properties("Updatability") = 7
How can I get an updatable ADODB Recordset from a Stored Procedure?4 years later...
I was having then same problem.
Finally, I've found how to "touch" the requierd bits.
Obviously, it's hardcore, but since some stupid at microsoft cannot understand the use of a disconnected recordset in the real world, there is no other choice.
Reference: http://download.microsoft.com/downlo...MS-ADTG%5D.pdf
http://msdn.microsoft.com/en-us/library/cc221950.aspx
http://www.xtremevbtalk.com/showthread.php?t=165799
Solution (VB6):
<pre>
Dim Rst As Recordset
Rst.Open "select 1 as C1, '5CHARS' as C5, sysdate as C6, NVL(null,15) as C7, null as C8 from DUAL", yourconnection, adOpenKeyset, adLockBatchOptimistic
Set Rst.ActiveConnection = Nothing
Dim S As New ADODB.Stream
Rst.Save S, adPersistADTG
Rst.Close
Set Rst = Nothing
With S
'Debug.Print .Size
Dim Bytes() As Byte
Dim WordVal As Integer
Dim LongVal As Long
Bytes = .Read(2)
If Bytes(0) <> 1 Then Err.Raise 5, , "ADTG byte 0, se esperaba: 1 (header)"
.Position = 2 + Bytes(1)
Bytes = .Read(3)
If Bytes(0) <> 2 Then Err.Raise 5, , "ADTG byte 9, se esperaba: 2 (handler)"
LongVal = Bytes(1) + Bytes(2) * 256 ' handler size
.Position = .Position + LongVal
Bytes = .Read(3)
If Bytes(0) <> 3 Then Err.Raise 5, , "ADTG, se esperaba: 3 (result descriptor)"
LongVal = Bytes(1) + Bytes(2) * 256 ' result descriptor size
.Position = .Position + LongVal
Bytes = .Read(3)
If Bytes(0) <> 16 Then Err.Raise 5, , "ADTG, se esperaba: 16 (adtgRecordSetContext)"
LongVal = Bytes(1) + Bytes(2) * 256 ' token size
.Position = .Position + LongVal
Bytes = .Read(3)
If Bytes(0) <> 5 Then Err.Raise 5, , "ADTG, se esperaba: 5 (adtgTableDescriptor)"
LongVal = Bytes(1) + Bytes(2) * 256 ' token size
.Position = .Position + LongVal
Bytes = .Read(1)
If Bytes(0) <> 6 Then Err.Raise 5, , "ADTG, se esperaba: 6 (adtgTokenColumnDescriptor)"
Do ' For each Field
Bytes = .Read(2)
LongVal = Bytes(0) + Bytes(1) * 256 ' token size
Dim NextTokenPos As Long
NextTokenPos = .Position + LongVal
Dim PresenceMap As Long
Bytes = .Read(3)
PresenceMap = Val("&H" & Right$("0" & Hex$(Bytes(0)), 2) & Right$("0" & Hex$(Bytes(1)), 2) & Right$("0" & Hex$(Bytes(2)), 2))
Bytes = .Read(2) 'ColumnOrdinal
'WordVal = Val("&H" & Right$("0" & Hex$(Bytes(0)), 2) & Right$("0" & Hex$(bytes(1)), 2))
'Aca pueden venir: friendly_columnname, basetable_ordinal,basetab_column_ordinal,basetab_colname
If PresenceMap And &H800000 Then 'friendly_columnname
Bytes = .Read(2) 'Size
LongVal = Bytes(0) + Bytes(1) * 256 ' Size
.Position = .Position + LongVal * 2 '*2 debido a UNICODE
End If
If PresenceMap And &H400000 Then 'basetable_ordinal
.Position = .Position + 2 ' 2 bytes
End If
If PresenceMap And &H200000 Then 'basetab_column_ordinal
.Position = .Position + 2 ' 2 bytes
End If
If PresenceMap And &H100000 Then 'basetab_colname
Bytes = .Read(2) 'Size
LongVal = Bytes(0) + Bytes(1) * 256 ' Size
.Position = .Position + LongVal * 2 '*2 debido a UNICODE
End If
Bytes = .Read(2) 'adtgColumnDBType
'WordVal = Val("&H" & Right$("0" & Hex$(Bytes(0)), 2) & Right$("0" & Hex$(bytes(1)), 2))
Bytes = .Read(4) 'adtgColumnMaxLength
'LongVal = Val("&H" & Right$("0" & Hex$(Bytes(3)), 2) & Right$("0" & Hex$(Bytes(2)), 2) & Right$("0" & Hex$(Bytes(1)), 2) & Right$("0" & Hex$(Bytes(0)), 2))
Bytes = .Read(4) 'Precision
'LongVal = Val("&H" & Right$("0" & Hex$(Bytes(3)), 2) & Right$("0" & Hex$(Bytes(2)), 2) & Right$("0" & Hex$(Bytes(1)), 2) & Right$("0" & Hex$(Bytes(0)), 2))
Bytes = .Read(4) 'Scale
'LongVal = Val("&H" & Right$("0" & Hex$(Bytes(3)), 2) & Right$("0" & Hex$(Bytes(2)), 2) & Right$("0" & Hex$(Bytes(1)), 2) & Right$("0" & Hex$(Bytes(0)), 2))
Dim ColumnFlags() As Byte, NewFlag0 As Byte
ColumnFlags = .Read(1) 'DBCOLUMNFLAGS, First Byte only (DBCOLUMNFLAGS=4 bytes total)
NewFlag0 = ColumnFlags(0)
If (NewFlag0 And &H4) = 0 Then 'DBCOLUMNFLAGS_WRITE (bit 2) esta OFF
'Lo pongo en ON, ya que quiero escribir esta columna LOCALMENTE en el rst DESCONECTADO
NewFlag0 = (NewFlag0 Or &H4)
End If
If (NewFlag0 And &H8) <> 0 Then 'DBCOLUMNFLAGS_WRITEUNKNOWN (bit 3) esta ON
'Lo pongo en OFF, ya que no me importa si NO sabes si se puede updatear no, yo lo se, no te preocupes
'ya que quiero escribir esta columna LOCALMENTE en el rst DESCONECTADO
NewFlag0 = (NewFlag0 And Not &H8)
End If
If (NewFlag0 And &H20) <> 0 Then 'DBCOLUMNFLAGS_ISNULLABLE (bit 5) esta OFF
'Lo pongo en ON, ya que siendo un RST DESCONECTADO, si le quiero poner NULL, le pongo y listo
NewFlag0 = (NewFlag0 Or &H20)
End If
If NewFlag0 <> ColumnFlags(0) Then
ColumnFlags(0) = NewFlag0
.Position = .Position - 1
.Write ColumnFlags
End If
.Position = NextTokenPos
Bytes = .Read(1)
Loop While Bytes(0) = 6
'Reconstruyo el Rst desde el stream
S.Position = 0
Set Rst = New Recordset
Rst.Open S
End With
'TEST IT
On Error Resume Next
Rst!C1 = 15
Rst!C5 = "MUCHOS CHARS"
Rst!C7 = 23423
If Err.Number = 0 Then
MsgBox "OK"
Else
MsgBox Err.Description
End If
</pre> -
Retruring Multiple rows from a Stored Procedure
The Oracle JDBC documentation shows how to return a cursor pointer through the parameter list of a stored procedure allowing a Java program to use the cursor like a normal result set. I've tried it (using the thin driver) and it works fine - however, I'm having trouble getting this to work running the program under a Weblogic server (using their own JDBC implementation). So, I have two questions:
1) Has anyone had this problem before and solved it ??
2) Are there any other techniques for getting multiple rows back from the database without having to fire "raw" sql at it ?Hi
You could return not resultset but array, for example:
PACKAGE TEST:
type string_table is table of varchar2(80)
index by binary_integer;
function get_something (
something1 out string_table,
arraylength in number
) return number;
PACKAGE'S BODY:
function get_something (
something1 out string_table,
arraylength in number /** length of the array **/
) return number as
cursor C is
select something1, ...
from test_table;
pos number := 1;
begin
for position in C loop
exit when (pos > arraylength);
something1(pos) := position.something1;
pos := pos + 1;
end loop;
return (pos - 1);
end;
Of course in this example you need to know length of your array
(arraylength parameter), but you can avoid such problem, for
example, by using DBMS_SQL package (or dynamic SQL feature in
the Oracle8i).
Andrew
Mladen Gogala (guest) wrote:
: Phil Hildebrand (guest) wrote:
: : Is there a way that I can return multiple rows from a stored
: : procedure for function ?
: : Something like:
: : CREATE FUNCTION sp_get_children (my_nip IN port.nip_num%
TYPE)
: : RETURN my_nip
: : IS
: : CURSOR child_cur IS
: : SELECT nip_num
: : FROM logical_port
: : WHERE port_num = my_nip;
: : child_rec child_cur%rowtype;
: : BEGIN
: : FOR child_rec IN child_cur
: : LOOP
: : RETURN my_nip;
: : END LOOP;
: : END tmp_sp_get_children;
: : I know how to do it in Informix ( RETURN WITH RESUME ), but
: I'm
: : not running Informix ;)
: : Thanks,
: : Phil
: In contrast with Informix, SQL Server and Sybase, Oracle
: can not return a result set. the only workaround is to
: return the cursor variable as such.
null -
Table of records from a stored procedure
Hi
Where could I find an example or documentation about how to retrive a table of records from a Stored Procedure ??
ThanksTry:
CREATE OR REPLACE TYPE scott.MYRECORDTYPE as object
(a int, b varchar2(40), c date, d number(10));
CREATE OR REPLACE TYPE scott.MYTABLETYPE is table of myrecordtype;
CREATE OR REPLACE PACKAGE BODY scott.MYPACKAGE
as
type number_collection is table of number(38) index by binary_integer;
type varchar2_collection is table of varchar2(4000) index by binary_integer;
type date_collection is table of date index by binary_integer;
g_data myTableType;
empno_col number_collection;
ename_col varchar2_collection;
hiredate_col date_collection;
mgr_col number_collection;
function my_function return myTableType
is
begin
select empno, ename, hiredate, mgr
bulk collect into empno_col, ename_col, hiredate_col, mgr_col
from emp
order by empno; -- Get some data
g_data := myTableType(); -- Initialize
for i in empno_col.first .. empno_col.last loop
g_data.extend; -- Write something in the array
g_data(i) := myRecordtype(empno_col(i), ename_col(i), hiredate_col(i), mgr_col(i));
end loop;
return g_data;
end;
end;
-- Demonstration-View
CREATE OR REPLACE VIEW scott.myview
AS
select a,b,c,d
from table(cast(myPackage.my_function() as mytabletype)); -
Returning a table from a stored procedure
hi, i need to return a table from a stored procedure and show it, and come to this, but a don't know hoy to run it, so i don't know if it is right, can anyone help me?
uTable out objects_uptime%rowtype
as
begin
select * into uTable from objects_uptime;
end;well, i finally discovered how to do the trick
this is the code for the function:
CREATE OR REPLACE FUNCTION FN_GET_RECORDS RETURN UPTIME PIPELINED IS
CURSOR cUptime is select * from objects_uptime;
p refcur.refcur_t;
temp p%ROWTYPE;
temp2 OUPTIME := OUPTIME(null, null, null, null, null, null, null, null, null);
BEGIN
OPEN cUptime;
LOOP
FETCH cUptime into temp;
temp2.OBJ_NAME := temp.OBJ_NAME;
temp2.IP := temp.IP;
temp2.STATUS := temp.STATUS;
temp2.DOE := temp.DOE;
temp2.ENABLED := temp.ENABLED;
temp2.COMMENT00000 := temp.COMMENT00000;
temp2.USERID := temp.USERID;
temp2.OBJECTID := temp.OBJECTID;
temp2.MNTID := temp.MNTID;
pipe row(temp2);
EXIT WHEN cUptime%NOTFOUND;
END LOOP;
RETURN;
END FN_GET_RECORDS;
and this for the auxiliar package, object and table:
CREATE OR REPLACE PACKAGE REFCUR
as
TYPE refcur_t IS REF CURSOR RETURN objects_uptime%ROWTYPE;
end REFCUR;
CREATE OR REPLACE TYPE OUPTIME AS OBJECT ( "OBJ_NAME"
VARCHAR2(255), "IP" VARCHAR2(20), "STATUS" VARCHAR2(10),
"DOE" DATE, "ENABLED" NUMBER(10, 1), "COMMENT00000"
VARCHAR2(1000), "USERID" VARCHAR2(50), "OBJECTID" NUMBER(10,
1), "MNTID" NUMBER(10, 1) )
CREATE TYPE TUPTIME AS
TABLE OF OUPTIME
i call it this way:
select * from table(FN_GET_RECORDS ())
if anyone knows how to do the same in a shorter manner, tell me please.
thanks to everybody for the help. -
Copy values from stored procedure to a text pad
Any Suggestions
We have a table 'A' and wrote a select query to get the values from that table 'A'. I place this select query in Stored procedure and when I run that procedure every month the output should be sent t a text pad. Any suggestions how to write it
thanks
Is there any other method if we dont have the privelage to create directory?
Edited by: user646635 on Oct 2, 2008 7:16 AMuser646635 wrote:
want to store the output in a text file?
we are using oracle 9iHere's a basic example for you...
AS SYS:
create or replace directory TEST_DIR as 'c:\test_dir'; -- This creates an oracle directory object. The actual operating system directory must be created manually
grant read,write on directory test_dir to my_user; -- Grant permission to use that directory object to the required user(s)AS my_user:
declare
cursor cur_emp is
select ename, deptno
from emp;
v_fh UTL_FILE.FILE_TYPE; -- This is a file handle
begin
v_fh := UTL_FILE.FOPEN('TEST_DIR', 'file.txt', 'w', 32767); -- Open the file for writing and obtain a handle to it
FOR i IN cur_emp -- process the query in a loop
LOOP
UTL_FILE.FPUT_LINE(v_fh, i.ename||','||to_char(i.deptno,'fm099')); -- write out lines of text to the file
END LOOP;
UTL_FILE.FCLOSE(v_fh); -- Close the file (also flushes any unwritten buffered data).
end;
Maybe you are looking for
-
Using a mac as a wireless media server
Can a G5 or Mac Pro be setup to share music, videos, and pictures wirelessly without needing a monitor, keyboar, or mouse? I would like to be able to set the mac up somewhere not visible, and never have to access it directly. I would like to add new
-
JNDI Lookup in JSP fails for EJB 3.0
I am new to Java technology. I read the EJB FAQ, NetBeans docs and may forum discussions and I am still confused with the error I am having. Background: I have developed a persistance bean and related sessions beans (similar to the customer-cmp-ear a
-
Hard Disk Failure - Please Help
Hi, I have a HP probook 4730s. The laptop is 13 months old and the warranty has expired. The HDD has been laging lateley and also the system restore took, the last time it was ran took longer as usual, now at the startup i receive a message that the
-
Number of records in cube from Query Designer
I don't have access to the cube in BW(listschema). I only have access to pull reports from cube from Query Designer. How can I tell the total number of records in a cube? Thanks.
-
Dump in Value-Help Component for date
I created a Value-Help-Component for date fields. (I cannot use the standard value help, because I need the help to start in the month, the user is working on). I am using the Date Navigator to select a date. If I first change the month with an arrow