Question is :
Create a Function named 'credit_limit' which takes shipment entity id(i.e, entity_id) as input and returns the limit_status of type varchar.
Function name : credit_limit
Input Parameter : entity_id in int
Output variable : limit_status variable of type varchar
Design rules:
1. If the credit_limit of the given entity id is greater then 50000,then display the limit_status as 'Credit limit is greater than 50000'
2. If the credit_limit of the given entity id is less then 50000,then display the limit_status as 'Credit limit is less than 50000'
Note: DO NOT CHANGE the given status message in your solution.
create or replace function credit_limit (entity_id in integer)
return varchar
is
c_credit_limit NUMBER(*,2);
limit_status varchar(255);
begin
select credit_limit into c_credit_limit from shipment_entity
where id = entity_id;
return(c_credit_limit);
if c_credit_limit > 50000 then
limit_status := 'Credit limit is greater than 50000';
else
if c_credit_limit < 50000 then
limit_status := 'Credit limit is less than 50000';
end if;
return (limit_status);
end;
/
I entered the code received an error
Warning: Function created with compilation errors.
please help me out.
You get issue because of 2 reasons:
1) You can return only once from a Function. You used it multiple times.
2) END IF is missing in one of the IF-ENDIF block.
Modifed code is:
CREATE OR REPLACE FUNCTION credit_limit (entity_id IN INTEGER)
RETURN VARCHAR2
IS
c_credit_limit NUMBER (5, 2);
limit_status VARCHAR (255);
BEGIN
SELECT credit_limit
INTO c_credit_limit
FROM shipment_entity
WHERE id = entity_id;
IF c_credit_limit > 50000
THEN
limit_status := 'Credit limit is greater than 50000';
ELSE
IF c_credit_limit < 50000
THEN
limit_status := 'Credit limit is less than 50000';
END IF;
END IF;
RETURN (c_credit_limit);
END;
/
Related
Here is my procedure where i want to insert values with the conditions like emp id start with sequence 131, phone number must be 13 digits, hire date not greater than sys date and salary not greater than 50,000. while executing im facing error . how to solve this.
create or replace procedure empinsert AS
cursor employee is select length(PHONE_NUMBER),HIRE_DATE,SAL from emp;
e_mobile_no emp.phone_number%type;
e_hire_date emp.hire_date%type;
e_salary emp.sal%type;
Begin
open employee ;
loop
fetch employee into e_mobile_no,e_hire_date,e_salary;
if ( e_mobile_no = 13 and e_hire_date < sysdate and e_salary <=50000 ) then
INSERT INTO EMP (EMP_ID,
EMP_NAME,
EMAIL,
PHONE_NUMBER,
HIRE_DATE,
JOB_ID,
SAL)
values(empinc.nextval, 'ramji','ramji#gmail.com','8975432109875','10/07/2021','JUN_TECH',40000);
else
exit;
end if;
end loop;
end;
/
I want to put single clob data column value in 2 varchar2 columns by checking the length of CLOB column, but i am getting error in case statement, line is marked in * *, it says syntex error , what am i doing wrong
DECLARE
v_tot_rows NUMBER (3);
rqst_xml_1 ISG.CERT_TEST_CASE_GTWY_TXN.RQST_XML_1_TX%TYPE;
rqst_xml_2 ISG.CERT_TEST_CASE_GTWY_TXN.RQST_XML_2_TX%TYPE;
CURSOR req_res_populate_cur
IS
SELECT scptc.SWR_CERT_PRJCT_TEST_CASE_ID,
orb_txn.MIME_HEAD_TX,
orb_txn.RSPNS_XML_TX,
orb_msg.RQST_GNRL_VLD_JSON_TX,
orb_msg.RQST_TEST_CASE_VLD_JSON_TX,
orb_msg.MRCH_ID
(
CASE
WHEN DBMS_LOB.GETLENGTH (orb_txn.RQST_XML_TX) <= 4000 THEN
rqst_xml_1 := CAST ( orb_txn . RQST_XML_TX AS VARCHAR2 ( 4000 ) ) * ,
rqst_xml_2 := ''
WHEN DBMS_LOB.GETLENGTH(orb_txn.RQST_XML_TX)>4000 THEN
rqst_xml_1:=CAST(substr(orb_txn.RQST_XML_TX,1,4000) AS VARCHAR2(4000)),
rqst_xml_2:=CAST(substr(orb_txn.RQST_XML_TX,4001)
END
)
FROM ISG.online_messages msg
JOIN ISG.SWR_CERT_PRJCT_TEST_CASE scptc
ON msg.online_message_id = scptc.TXN_ID,
ISG.GTWY_PLTFM_TXN_MSG orb_msg
JOIN ISG.GTWY_PLTFM_TXN orb_txn
ON orb_msg.GTWY_PLTFM_TXN_ID = orb_txn.GTWY_PLTFM_TXN_ID
WHERE msg.SPEC_ID = 60;;
BEGIN
FOR req_res IN req_res_populate_cur
LOOP
DBMS_OUTPUT.PUT_LINE (req_res.SWR_CERT_PRJCT_TEST_CASE_ID,
req_res.MIME_HEAD_TX,
req_res.rqst_xml_1,
req_res.rqst_xml_2,
req_res.RSPNS_XML_TX,
req_res.RQST_GNRL_VLD_JSON_TX,
req_res.RQST_TEST_CASE_VLD_JSON_TX,
req_res.MRCH_ID);
END LOOP;
END;
Your problem is your invalid SELECT-statement. You're trying to set variables (of your plsql-block) within a query. That's not intended or allowed.
You need to select the values into columns. Here i added two columns. One for each xml-value.
SELECT scptc.SWR_CERT_PRJCT_TEST_CASE_ID,
orb_txn.MIME_HEAD_TX,
orb_txn.RSPNS_XML_TX,
orb_msg.RQST_GNRL_VLD_JSON_TX,
orb_msg.RQST_TEST_CASE_VLD_JSON_TX,
orb_msg.MRCH_ID,
CASE --Column-Start
WHEN DBMS_LOB.GETLENGTH (orb_txn.RQST_XML_TX) <= 4000
THEN
CAST (orb_txn.RQST_XML_TX AS VARCHAR2 (4000))
WHEN DBMS_LOB.GETLENGTH (orb_txn.RQST_XML_TX) > 4000
THEN
CAST (
SUBSTR (orb_txn.RQST_XML_TX, 1, 4000) AS VARCHAR2 (4000))
END
AS my_rqst_xml_1, -- Column-End. In this column you'll have the value for xml_1
CASE --Column-Start
WHEN DBMS_LOB.GETLENGTH (orb_txn.RQST_XML_TX) <= 4000
THEN
''
WHEN DBMS_LOB.GETLENGTH (orb_txn.RQST_XML_TX) > 4000
THEN
CAST (SUBSTR (orb_txn.RQST_XML_TX, 4001) AS VARCHAR2 (4000))
END
AS my_rqst_xml_2 -- Column-End. In this column you'll have the value for xml_12
FROM ISG.online_messages msg
JOIN ISG.SWR_CERT_PRJCT_TEST_CASE scptc
ON msg.online_message_id = scptc.TXN_ID,
ISG.GTWY_PLTFM_TXN_MSG orb_msg
JOIN ISG.GTWY_PLTFM_TXN orb_txn
ON orb_msg.GTWY_PLTFM_TXN_ID = orb_txn.GTWY_PLTFM_TXN_ID
WHERE msg.SPEC_ID = 60
Afterwards you can work with the result and get the values from it.
BEGIN
FOR req_res IN req_res_populate_cur
LOOP
DBMS_OUTPUT.PUT_LINE (req_res.SWR_CERT_PRJCT_TEST_CASE_ID,
req_res.MIME_HEAD_TX,
req_res.my_rqst_xml_1, -- here we can see the values
req_res.my_rqst_xml_2, -- here too
req_res.RSPNS_XML_TX,
req_res.RQST_GNRL_VLD_JSON_TX,
req_res.RQST_TEST_CASE_VLD_JSON_TX,
req_res.MRCH_ID);
-- And here we could store the values into variables or call some procedures etc.
rqst_xml_1 := req_res.my_rqst_xml_1;
rqst_xml_2 := req_res.my_rqst_xml_2;
END LOOP;
END;
I've to guess, but it seems you didn't want to declare the variables:
rqst_xml_1 ISG.CERT_TEST_CASE_GTWY_TXN.RQST_XML_1_TX%TYPE;
rqst_xml_2 ISG.CERT_TEST_CASE_GTWY_TXN.RQST_XML_2_TX%TYPE;
This would be only needed if you want to work with the values.
I am trying to call a procedure using below code and getting
wrong number or types of arguments in call to procedure
The issue could be with the record type being passed as parameter , but I couldn't see any issue with that .
DECLARE
p_status VARCHAR2 (4) := 'S';
p_id NUMBER := 123456;
p_py_id NUMBER := 513;
p_type NUMBER := 1;
p_date_time DATE := TO_DATE ('10/01/2018 23:50:42', 'DD/MM/YYYY HH24:MI:SS');
p_os_pay NUMBER := 0;
p_ind VARCHAR2 (2) := 'Y';
p_confirm VARCHAR2 (2) := 'Y';
p_year NUMBER := 2018;
p_reason VARCHAR2 (5) := NULL;
p_currrpay NUMBER := 1517;
p_details pkg.g_r_type;
BEGIN
p_details.pro_code := 'AB';
p_details.inst_type := '1';
p_details.pay_date := TO_DATE ('19/10/2016 00:00:00', 'DD/MM/YYYY HH24:MI:SS');
p_details.pay_amt := 5000;
p_details.h_code := 'ABCD';
p_details.pay_ind := 'N';
p_details.c_code := 123456;
p_details.c_year := 8;
pkg.procedure_info ( p_status,
p_id,
p_py_id,
p_type,
p_date_time,
p_os_pay,
p_ind,
p_confirm,
p_year,
p_reason,
p_details,
p_currrpay
);
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (SQLERRM);
END;
/
Below is the package description :
CREATE OR REPLACE package pkg
as
type g_r_type is record (
pro_code varchar2 (2)
,inst_type varchar2 (1)
,pay_date date
,pay_amt number (13, 2)
,h_code varchar2 (4)
,pay_ind varchar2 (1)
,c_code number(6)
,c_year number(2)
);
procedure procedure_info (
p_status in varchar2
,p_id in number
,p_py_id in number
,p_type in number
,p_date_time in date
,p_os_pay in number
,p_ind in varchar2
,p_confirm in varchar2
,p_year in number
,p_failure_reason in varchar2
,p_details in g_r_type
,p_currrpay in number
);
end pkg;
/
I have cross checked the datatypes, length and number of arguments , but couldn't find the issue.
Make sure your package scripts end with a / at the very end of the text file, as the first char of the line (and last non blank).
If your package was created successfully, you should get a message:
package created successfully
Then if your package's Body is:
package body created successfully
To make sure your package is correctly created on the database:
This query should help:
Select * from all_source where name='PKG';
And for the body:
Select *
from all_source
where name='PKG'
and type='PACKAGE BODY';
I have a log table and the table has a varchar2 field which holds xml string like below:
In this example ClientName attribute did not change but Clientsurname changed.
I want to capture changed columns and their previous and new values.
The log table contains millions of records.
Which method can you suggest for parsing this data in an efficient way?
<r>
<columntag nameattribute="ClientName">
<new_value>Jeffrey</new_value>
<previous_value>Jeffrey</previous_value>
</columntag>
<columntag nameattribute="ClientSurname">
<new_value>Dijk</new_value>
<previous_value>Disk</previous_value>
</columntag>
</r>
Thank you
not 100% sure the below is what you are after but it should give you some ideas about how to go about it. Hope it is helpfull
CREATE TABLE "RM4SERV"."LOG_TEST" ( "TESTLOG" VARCHAR2(4000 BYTE))
Insert into RM4SERV.LOG_TEST (TESTLOG) values ('<r><columntag nameattribute="ClientName"><new_value>Jeffery</new_value><previous_value>Jeffery</previous_value> </columntag><columntag nameattribute="ClientSurname"><new_value>Dijk</new_value><previous_value>Disk</previous_value></columntag></r>');
Insert into RM4SERV.LOG_TEST (TESTLOG) values ('<r><columntag nameattribute="ClientName"><new_value>Jeffery</new_value><previous_value>Jeffery</previous_value> </columntag><columntag nameattribute="ClientSurname"><new_value>Disk</new_value><previous_value>Disk</previous_value></columntag></r>');
Insert into RM4SERV.LOG_TEST (TESTLOG) values ('<r><columntag nameattribute="ClientName"><new_value>Jeffery</new_value><previous_value>Jim</previous_value> </columntag><columntag nameattribute="ClientSurname"><new_value>Dijks</new_value><previous_value>Diskett</previous_value></columntag></r>');
declare
v_logrec varchar2(4000) := null;
v_recnum number := 0;
cursor c_logs is
select testlog from log_test;
cursor c_records is
select extractValue(x.column_value, '/columntag/#nameattribute') as column_name,
extractValue(x.column_value, '/columntag/new_value') as new_value,
extractValue(x.column_value, '/columntag/previous_value') as previous_value
from TABLE(XMLSequence(extract(xmltype.createxml(v_logrec), '//columntag'))) x
where extractValue(x.column_value, '/columntag/new_value') != extractValue(x.column_value, '/columntag/previous_value');
begin
for v_log in c_logs loop
v_logrec := v_log.testlog;
v_recnum := v_recnum + 1;
dbms_output.put_line(v_recnum);
for v_rec in c_records loop
SYS.dbms_output.put_line(v_rec.column_name || ' : *' || v_rec.new_value || '* : *' || v_rec.previous_value || '*');
end loop;
end loop;
end;
This would give you the below output (so Surname different in first record, nothing different in the second and both different in the third)...
1
ClientSurname : Dijk : Disk
2
3
ClientName : Jeffery : Jim
ClientSurname : Dijks : Diskett
I am trying to write a function to show values for monthly data according to the selection made by the user in monthly report. Code snippet below is just trying to fetch values in a nested table and once data is loaded successfully in a nested table, I will call the function to display the table. I have tried a few things; but am running into issues while loading data. Below are 2 different SQLs to create this function but both of them are getting same error regarding incorrect values; I have tried a few things but to no avail:
Snippet 1:
/* Formatted on 10/16/2012 8:40:45 AM (QP5 v5.215.12089.38647) */
CREATE OR REPLACE TYPE tempObject AS OBJECT
(
kpiid number,
kpigroup VARCHAR2 (300)
);
CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;
CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
mainarea IN VARCHAR2)
RETURN tempTable
IS
MonthlyData temptable := temptable ();
n INTEGER := 0;
BEGIN
IF (mainarea = 'ALL')
THEN
FOR r IN (SELECT DISTINCT kpiid, kpigroup
FROM kpi_summary_reporting
WHERE kpifrequency = 'Monthly' AND active_ind = 'Y')
LOOP
monthlydata.EXTEND;
n := n + 1;
monthlydata (n) := tempobject (r.kpiid, r.kpigroup);
END LOOP;
END IF;
RETURN MonthlyData;
END;
Error: [Error] PLS-00306 (26: 29): PLS-00306: wrong number or types of arguments in call to 'TEMPOBJECT'
Snippet2:
/* Formatted on 10/16/2012 8:27:22 AM (QP5 v5.215.12089.38647) */
CREATE OR REPLACE TYPE tempObject AS OBJECT
(
kpiid NUMBER,
kpigroup VARCHAR2 (300)
);
CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;
CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
mainarea IN VARCHAR2)
RETURN tempTable
AS
MonthlyData temptable := temptable ();
BEGIN
IF (mainarea = 'ALL')
THEN
SELECT DISTINCT ksr.kpiid, ksr.kpigroup
INTO MonthlyData
FROM kpi_summary_reporting ksr
WHERE kpifrequency = 'Monthly' AND active_ind = 'Y';
ELSE
SELECT DISTINCT kpiid, kpigroup
INTO MonthlyData
FROM kpi_summary_reporting;
END IF;
RETURN MonthlyData;
END;
Error: [Error] ORA-00947 (24: 9): PL/SQL: ORA-00947: not enough values
I would do something like this assuming that the data is small enough that it really makes sense to load it entirely into a nested table in the server's PGA. If the data volume is larger, you probably want to use a pipelined table function instead.
Since your nested table is a table of object types, you need to use the object type constructor.
CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
mainarea IN VARCHAR2)
RETURN tempTable
IS
MonthlyData temptable;
BEGIN
IF (mainarea = 'ALL')
THEN
SELECT tempObject( kpiid, kpigroup )
BULK COLLECT INTO monthlydata
FROM kpi_summary_reporting
WHERE kpifrequency = 'Monthly'
AND active_ind = 'Y';
END IF;
RETURN MonthlyData;
END;
I'm always dubious when I see a DISTINCT in a query. Do you really expect to get duplicate rows that you need to remove? If not, you'll be much better served removing the DISTINCT as I did above. If you really need the DISTINCT, then your object type would need a MAP or an ORDER method which would complicate the example a bit.
A demonstration of this working
SQL> CREATE OR REPLACE TYPE tempObject AS OBJECT
2 (
3 kpiid NUMBER,
4 kpigroup VARCHAR2 (300)
5 );
6 /
Type created.
SQL> CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;
2 /
Type created.
SQL> create table kpi_summary_reporting (
2 kpiid integer,
3 kpigroup varchar2(300),
4 kpifrequency varchar2(30),
5 active_ind varchar2(1)
6 );
Table created.
SQL> insert into kpi_summary_reporting values( 1, 'Foo', 'Monthly', 'Y' );
1 row created.
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE FUNCTION Monthly_All_Data (
2 mainarea IN VARCHAR2)
3 RETURN tempTable
4 IS
5 MonthlyData temptable;
6 BEGIN
7 IF (mainarea = 'ALL')
8 THEN
9 SELECT tempObject( kpiid, kpigroup )
10 BULK COLLECT INTO monthlydata
11 FROM kpi_summary_reporting
12 WHERE kpifrequency = 'Monthly'
13 AND active_ind = 'Y';
14 END IF;
15 RETURN MonthlyData;
16* END;
17 /
Function created.
SQL> select monthly_all_data( 'ALL' ) from dual;
MONTHLY_ALL_DATA('ALL')(KPIID, KPIGROUP)
--------------------------------------------------------------------------------
TEMPTABLE(TEMPOBJECT(1, 'Foo'))