Oracle: Inconsistent Datatype Issue - oracle

I am getting inconsistent datatype error message and I am not sure why. I need some guidance to figure this out.
I am creating two types as:
My universe table have following columns with column type:
Column Name Data Type
PON VARCHAR2(25 BYTE)
RPON VARCHAR2(25 BYTE)
SUPPLIER_NAME VARCHAR2(255 BYTE)
SUB_SUPPLIER_NAME VARCHAR2(255 BYTE)
SOURCE_NO VARCHAR2(40 BYTE)
CKR VARCHAR2(200 BYTE)
LEC_ID VARCHAR2(200 BYTE)
ICSC VARCHAR2(10 BYTE)
ACTL_ST VARCHAR2(10 BYTE)
ADW_ST VARCHAR2(10 BYTE)
PROJ_ID VARCHAR2(100 BYTE)
MOVE_TO_INV_DT DATE
IE_DT DATE
DDD_DT DATE
EFF_BILL_DT DATE
ACTION VARCHAR2(10 BYTE)
SERVICE VARCHAR2(10 BYTE)
AFP VARCHAR2(10 BYTE)
ACNA VARCHAR2(10 BYTE)
SERVICE_NAME VARCHAR2(255 BYTE)
UPLOAD_DT DATE
PROGRAM VARCHAR2(50 BYTE)
INITIATIVE_ID NUMBER
ACOST NUMBER
ACOST_IND VARCHAR2(25 BYTE)
MAPFILE VARCHAR2(100 BYTE)
Row Type
create or replace
TYPE test_COMP_REPORT_ROW_TYPE AS OBJECT (
PON VARCHAR2(25 BYTE),
RPON VARCHAR2(25 BYTE),
VENDOR VARCHAR2(255 BYTE),
SUB_SUPPLIER VARCHAR2(255 BYTE),
SOURCE_NO VARCHAR2(40 BYTE),
ATT_CKT_ID VARCHAR2(200 BYTE),
LEC_ID VARCHAR2(200 BYTE),
ICSC VARCHAR2(10 BYTE),
STATE VARCHAR2(10 BYTE),
PROJECT_ID VARCHAR2(100 BYTE),
ACTION VARCHAR2(10 BYTE),
SERVICE_SPEED VARCHAR2(10 BYTE),
SERVICE_NAME VARCHAR(255 BYTE),
INEFFECT_DATE DATE,
EVENT_DATE DATE,
DUE_DATE DATE,
ACOST NUMBER
)
Tab Type
create or replace type test_COMP_REPORT_TAB_TYPE
AS TABLE OF test_COMP_REPORT_ROW_TYPE
Here is the Function which is using this type:
create or replace
FUNCTION test_comp_report_func
(
start_dt_h IN VARCHAR2 DEFAULT NULL,
end_dt_h IN VARCHAR2 DEFAULT NULL,
year_h IN VARCHAR2 DEFAULT NULL )
RETURN test_comp_report_tab_type pipelined
IS
e_sql LONG;
program_v VARCHAR2(10);
v_row test_comp_report_row_type := test_comp_report_row_type(NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
);
TYPE rectyp IS REF CURSOR;
rrc_rectyp rectyp;
TYPE recordvar IS RECORD
(
PON VARCHAR2(25 BYTE),
RPON VARCHAR2(25 BYTE),
VENDOR VARCHAR2(255 BYTE),
SUB_SUPPLIER VARCHAR2(255 BYTE),
SOURCE_NO VARCHAR2(40 BYTE),
ATT_CKT_ID VARCHAR2(200 BYTE),
LEC_ID VARCHAR2(200 BYTE),
ICSC VARCHAR2(10 BYTE),
STATE VARCHAR2(10 BYTE),
PROJECT_ID VARCHAR2(100 BYTE),
ACTION VARCHAR2(10 BYTE),
SERVICE_SPEED VARCHAR2(10 BYTE),
SERVICE_NAME VARCHAR(255 BYTE),
INEFFECT_DATE DATE,
EVENT_DATE DATE,
DUE_DATE DATE,
ACOST NUMBER
);
res_rec recordvar;
BEGIN
e_sql := e_sql || 'SELECT
PON,
RPON,
SUPPLIER_NAME VENDOR,
SUB_SUPPLIER_NAME SUB_SUPPLIER,
SOURCE_NO,
CKR,
LEC_ID,
ICSC,
ACTL_ST,
ADW_ST STATE,
PROJ_ID,
ACTION,
SERVICE SPEED,
AFP,
ACNA,
SERVICE_NAME,
IE_DT,
MOVE_TO_INV_DT EVENTDAT,
DDD_DT DUEDATE,
EFF_BILL_DT,
ACOST
FROM UNIVERSE
WHERE to_date(IE_DT) between to_date(nvl(''01/01/2000'', ''01/01/2000''), ''MM/DD/YYYY'')
and to_date(nvl(''12/31/2009'', to_char(trunc(add_months(sysdate, 12),''year'')-1,''MM/DD/YYYY'')), ''MM/DD/YYYY'')
AND PROGRAM = ''T45sONNET''
AND nvl(trim(ACOST_IND), ''NULL'') not in (''INVALID-2005'')
ORDER BY ACTION';
dbms_output.put_line(e_sql);
OPEN rrc_rectyp FOR e_sql;
LOOP
FETCH rrc_rectyp INTO res_rec;
EXIT WHEN rrc_rectyp%NOTFOUND;
v_row.PON := res_rec.PON;
v_row.RPON := res_rec.RPON;
v_row.VENDOR := res_rec.VENDOR;
v_row.SUB_SUPPLIER := res_rec.SUB_SUPPLIER;
v_row.SOURCE_NO := res_rec.SOURCE_NO;
v_row.ATT_CKT_ID := res_rec.ATT_CKT_ID;
v_row.LEC_ID := res_rec.LEC_ID;
v_row.ICSC := res_rec.ICSC;
v_row.STATE := res_rec.STATE;
v_row.PROJECT_ID := res_rec.PROJECT_ID;
v_row.ACTION := res_rec.ACTION;
v_row.SERVICE_SPEED := res_rec.SERVICE_SPEED;
v_row.SERVICE_NAME := res_rec.SERVICE_NAME;
v_row.INEFFECT_DATE := res_rec.INEFFECT_DATE;
v_row.EVENT_DATE := res_rec.EVENT_DATE;
v_row.DUE_DATE := res_rec.DUE_DATE;
v_row.ACOST := res_rec.ACOST;
pipe ROW(v_row);
END LOOP;
return;
end test_comp_report_func;
I have tried to debug issue but still am not able to find my way out and would appreciate if SO Community can guide.

I first wrote an answer trying to reproduce your error but you've changed your question quite a bit so I'm starting again from scratch.
First a few remarks:
By your own account you're quite new to PL/SQL yet you're using pretty advanced features: dynamic SQL, pipelined functions, SQL Objects. Let's try to begin with something simpler at first (I'll show you how you can work with static SQL, this would be sufficient 99.9% of the time).
When you hit a problem you need to decompose your code to see what is working and what is not. That usually means simplifying your code until it is so simple it starts to work, then bring back the complex elements of your code one by one until you hit the problem again.
When you provide a test case, try to make it as simple as possible :) It'll be easier for people to help you, but more importantly in most of the cases, building the test case will help you find the solution yourself since this will force you to decompose your complex code (see previous point). My rule of thumb (FWIW) is that code that is displayed with a scroll bar (either horizontal or vertical) in SO is too big for a test case and needs to be trimmed if possible.
I ran your code and got the ORA-00932 on the fetch line. When I replace the SQL with static SQL the error is more explicit:
SQL> CREATE OR REPLACE FUNCTION test_comp_report_func
2 RETURN test_comp_report_tab_type
3 PIPELINED IS
4 TYPE recordvar IS RECORD(
5 PON VARCHAR2(25 BYTE),
(...snip...)
21 ACOST NUMBER);
22 res_rec recordvar;
23 v_row test_COMP_REPORT_ROW_TYPE;
24 CURSOR rrc_rectyp IS
25 SELECT PON,
(...snip...)
45 ACOST
46 FROM UNIVERSE;
48 BEGIN
49 OPEN rrc_rectyp;
50 LOOP
51 FETCH rrc_rectyp
52 INTO res_rec;
54 EXIT WHEN rrc_rectyp%NOTFOUND;
55 /*...*/
56 PIPE ROW(v_row);
57 END LOOP;
58 RETURN;
59 END test_comp_report_func;
60 /
Warning: Function created with compilation errors.
LINE/COL ERROR
-------- -----------------------------------------------------------------
51/7 PL/SQL: SQL Statement ignored
52/15 PLS-00386: type mismatch found at 'RES_REC' between FETCH cursor
and INTO variables
Here the problem comes from the fact that your select statement doesn't have the same number of columns as the number of fields in your record. You can use %rowcount to prevent this:
CREATE OR REPLACE FUNCTION test_comp_report_func
RETURN test_comp_report_tab_type
PIPELINED IS
v_row test_COMP_REPORT_ROW_TYPE;
CURSOR rrc_rectyp IS
SELECT PON, RPON, SUPPLIER_NAME VENDOR, SUB_SUPPLIER_NAME SUB_SUPPLIER,
SOURCE_NO, CKR, LEC_ID, ICSC, ACTL_ST, ADW_ST STATE, PROJ_ID,
ACTION, SERVICE SPEED, AFP, ACNA, SERVICE_NAME, IE_DT,
MOVE_TO_INV_DT EVENTDAT, DDD_DT DUEDATE, EFF_BILL_DT, ACOST
FROM UNIVERSE;
res_rec rrc_rectyp%ROWTYPE;
BEGIN
OPEN rrc_rectyp;
LOOP
FETCH rrc_rectyp
INTO res_rec;
EXIT WHEN rrc_rectyp%NOTFOUND;
v_row.pon := res_rec.pon;
/*...*/
PIPE ROW(v_row);
END LOOP;
RETURN;
END test_comp_report_func;
You can even fetch the SQL object directly (with an implicit cursor):
CREATE OR REPLACE FUNCTION test_comp_report_func
RETURN test_comp_report_tab_type
PIPELINED IS
BEGIN
FOR res_rec IN (SELECT test_comp_report_row_type(PON, RPON, SUPPLIER_NAME,
SUB_SUPPLIER_NAME,SOURCE_NO,
CKR, LEC_ID, ICSC, ACTL_ST,
PROJ_ID, ACTION, SERVICE,
SERVICE_NAME, IE_DT, DDD_DT,
EFF_BILL_DT, ACOST)my_object
FROM UNIVERSE) LOOP
PIPE ROW(res_rec.my_object);
END LOOP;
RETURN;
END test_comp_report_func;

You're getting the error because the SQL query in e_sql is returning four more values than are in res_rec. The cursor returns 21 columns of data but your recordvar record type only contains 17 fields.
It looks to me like the columns ACTL_ST, AFP, ACNA and EFF_BILL_DT don't map to anything in res_rec, and if you remove these from the query you should find that your function no longer reports the inconsistent datatypes error.
I would probably have implemented the function something like the following:
CREATE OR REPLACE FUNCTION test_comp_report_func_2 (
start_dt_h IN VARCHAR2 DEFAULT NULL,
end_dt_h IN VARCHAR2 DEFAULT NULL,
year_h IN VARCHAR2 DEFAULT NULL
) RETURN test_comp_report_tab_type PIPELINED
IS
CURSOR cur_res_rec IS
SELECT PON,
RPON,
SUPPLIER_NAME VENDOR,
SUB_SUPPLIER_NAME SUB_SUPPLIER,
SOURCE_NO,
CKR ATT_CKT_ID,
LEC_ID,
ICSC,
ACTL_ST,
ADW_ST STATE,
PROJ_ID AS PROJECT_ID,
ACTION,
SERVICE SERVICE_SPEED,
AFP,
ACNA,
SERVICE_NAME,
IE_DT INEFFECT_DATE,
MOVE_TO_INV_DT EVENT_DATE,
DDD_DT DUE_DATE,
EFF_BILL_DT,
ACOST
FROM UNIVERSE
WHERE TO_DATE(IE_DT) BETWEEN TO_DATE(NVL('01/01/2000', '01/01/2000'), 'MM/DD/YYYY')
AND TO_DATE(NVL('12/31/2009', TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, 12),'year') - 1,'MM/DD/YYYY')), 'MM/DD/YYYY')
AND PROGRAM = 'T45sONNET'
AND NVL(TRIM(ACOST_IND), 'NULL') NOT IN ('INVALID-2005')
ORDER BY ACTION;
v_row test_comp_report_row_type := test_comp_report_row_type(NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
BEGIN
FOR res_rec IN cur_res_rec
LOOP
v_row.PON := res_rec.PON;
v_row.RPON := res_rec.RPON;
v_row.VENDOR := res_rec.VENDOR;
v_row.SUB_SUPPLIER := res_rec.SUB_SUPPLIER;
v_row.SOURCE_NO := res_rec.SOURCE_NO;
v_row.ATT_CKT_ID := res_rec.ATT_CKT_ID;
v_row.LEC_ID := res_rec.LEC_ID;
v_row.ICSC := res_rec.ICSC;
v_row.STATE := res_rec.STATE;
v_row.PROJECT_ID := res_rec.PROJECT_ID;
v_row.ACTION := res_rec.ACTION;
v_row.SERVICE_SPEED := res_rec.SERVICE_SPEED;
v_row.SERVICE_NAME := res_rec.SERVICE_NAME;
v_row.INEFFECT_DATE := res_rec.INEFFECT_DATE;
v_row.EVENT_DATE := res_rec.EVENT_DATE;
v_row.DUE_DATE := res_rec.DUE_DATE;
v_row.ACOST := res_rec.ACOST;
PIPE ROW(v_row);
END LOOP;
RETURN;
END test_comp_report_func_2;
/
Firstly, I can't honestly see the reason you're using dynamic SQL. The function above uses a 'static' SQL query, and it has the advantage that Oracle will check that this query is valid when it compiles the function. If there's an error with the query, the function won't compile. On the other hand, if you have an error with a dynamic SQL query, you won't find out that there's a problem until you run your function.
Dynamic SQL is useful if you want to change the structure of a query, e.g. to run it on different tables or change the columns used in a WHERE clause. However, most of the time you don't need to do this. Dynamic SQL is one of those things you really shouldn't use if you don't need to use it.
Also, by using FOR some_record IN some_cursor, I don't have to fiddle around with opening and closing a cursor, nor do I need to check whether there's any more data left and exit the loop if so. It also cuts out having to declare a variable for the row record (res_rec) or getting the type of this variable wrong. That is all done automatically for me.

Related

PL/SQL XML desctructuring: XVM-01081: [XPST0081] Invalid prefix

I am trying to read xml clob file with multiple namespaces. I am just literally out of ideas, spent few hours on this.
My test case looks like:
declare
test_msg clob;
begin
test_msg := to_clob(
'
<testReq xmlns="http://test/xxx/xxx-xxx/v1">
<id>HelloWorld</id>
<numer>HelloWorld</numer>
<typ>COGR</typ>
<czyAktywny>T</czyAktywny>
<a:fieldone xmlns:a="http://xxx/yyy/zzz/v1">
<a:sym>HelloWorld</a:sym>
<a:sympod>HelloWorld</a:sympod>
</a:fieldone>
</testReq>
'
);
-- Call the function
:result := i_mypackage_pkg.odbierzReq(p_komunikatWej => test_msg,
p_logId => 12344);
end;
Where my implementation of xml_table looks like:
from xmltable(xmlnamespaces('http://test/xxx/xxx-xxx/v1' as "model"
,'http://xxx/yyy/zzz/v1' as "adres"),
'//model:testReq' passing xmlType(p_komunikatWej)
columns
id varchar2(20 char) path 'model:id'
,numer varchar2(20 char) path 'model:numer'
,typ varchar2(20 char) path 'model:typ'
,czyAktywny varchar2(1 char) path 'model:czyAktywny'
-- dane adresowe punktu poboru
,kod varchar2(7 char) path 'adres:fieldone/a:sympod'
) t;
And the exception looks like this:
XVM-01081: [XPST0081] Invalid prefix
1 declare namespace model="http://test/xxx/xxx-xxx/v1";declare namesp
- ^
I am literally out of ideas. Any help would be appreciated. Thanks
EDIT
Solved by updating namespace alias:
'http://xxx/yyy/zzz/v1' as "a"
As well as using a/adres consistently, you can simplify your paths by declaring a default namespace instead of adding model:
from xmltable(xmlnamespaces(default 'http://test/xxx/xxx-xxx/v1'
,'http://xxx/yyy/zzz/v1' as "a"),
'/testReq' passing xmlType(p_komunikatWej)
columns
id varchar2(20 char) path 'id'
,numer varchar2(20 char) path 'numer'
,typ varchar2(20 char) path 'typ'
,czyAktywny varchar2(1 char) path 'czyAktywny'
-- dane adresowe punktu poboru
,kod varchar2(7 char) path 'a:fieldone/a:sympod'
) t;
db<>fiddle demo using a CTE instead of PL/SQL.

PLS-00215 String length constraints must be in range

CREATE TABLE INTERVENCIONES(
"IDINTERVENCION" INTEGER PRIMARY KEY,
"NOMBREINTERVENCION" VARCHAR2(50 BYTE) NOT NULL,
"TIEMPOESPERADO" VARCHAR2(50 BYTE),
"NIF" CHAR(9 BYTE) REFERENCES VETERINARIOS NOT NULL,
"NUMEROCLIENTE" INTEGER REFERENCES CLIENTES NOT NULL,
"DIFICULTAD" CHAR (8 BYTE), CONSTRAINT "INTERVENCIONES_1"
CHECK (DIFICULTAD IN ('BAJA','MODERADA','ALTA','OTRO'))
);
CREATE OR REPLACE TRIGGER TRG_INTERVENCIONES BEFORE INSERT OR UPDATE ON INTERVENCIONES
FOR EACH ROW
DECLARE
LV_DIF VARCHAR2 := :NEW.DIFICULTAD;
LV_TIM NUMBER := :NEW.TIEMPOESPERADO;
BEGIN
IF (LV_DIF LIKE 'BAJA' AND (LV_TIM>1)) THEN
RAISE_APPLICATION_ERROR (num => 20005, msg => 'Siendo de riesgo bajo, debe durar menos de 1 hora');
END IF;
END;
I want that if DIFICULTAD equals BAJA, TIEMPOESPERADO has to be more than 1. The error is:
PLS-00215 String length constraints must be in range
you don't actually need to define local variables.
IF (:NEW.DIFICULTAD LIKE 'BAJA' AND (:NEW.TIEMPOESPERADO > 1)) THEN
but if you want to define, you should do it right. varchar must be defined with an indication of the length: VARCHAR2(<length>)
pay attention to the length information. The can be the number of characters or bytes. that depends on the configuration of your database
e.g.
LV_DIF VARCHAR2(200) := :NEW.DIFICULTAD; -- 200

Oracle select count(*) into n generates ORA-01401 inserted value too large for column

I have spent hours tracking down the source of this bug and am stumped. I managed to determine that the below simple select statement was the problem (comment and not error.. so yes, it's the cause). n was initially defined as a number, I tried integer as well for grins.
n integer;
n := 1;
select count(*) into n
from category
where (
upper(ltrim(rtrim(category_long_name))) = upper(ltrim(rtrim(cat_long_name)))
or
upper(ltrim(rtrim(category_short_name))) = upper(ltrim(rtrim(cat_short_name)))
or
upper(ltrim(rtrim(category_description))) = upper(ltrim(rtrim(cat_descr)))
)
and (settings_setting_id = sett_id) and (category_id <> cat_id);
When this code is executed, I get ORA-01401: inserted value too large for column. So the only "insert" is into the n value for a row count. The actual value (used debugger) is 0.
I don't understand how this could be causing a problem. I've seen this select count(*) into x code snippet in examples. The procedure runs fine with this statement commented out. The only time 'n' is used is in the next step where I raise and exception if it's > 0. I've literally commented out the entire stored procedure, leaving only this statement, and it causes the error.
My research online indicates that count(*) returns an integer.
The category table has about 50 rows in it.
What am I missing?
This is category:
"CATEGORY_ID" NUMBER(,0),
"VERSION_VERSION_ID" NUMBER(,0),
"SETTINGS_SETTING_ID" NUMBER(*,0),
"CATEGORY_LONG_NAME" CHAR(256 BYTE),
"CATEGORY_SHORT_NAME" CHAR(25 BYTE),
"CATEGORY_DESCRIPTION" VARCHAR2(4000 BYTE),
"CATEGORY_FORM_ID" CHAR(10 BYTE),
"CATEGORY_FORM_SYNONYM" CHAR(256 BYTE),
"CATEGORY_GUIDE_FOR_USE" VARCHAR2(4000 BYTE),
"CATEGORY_COMMENTS" VARCHAR2(4000 BYTE),
"CATEGORY_EFFECTIVE_DATE" DATE,
"CATEGORY_UNTIL_DATE" DATE,
"CATEGORY_CREATOR" CHAR(50 BYTE),
"CATEGORY_ADMIN_STATUS" CHAR(25 BYTE),
"CATEGORY_ADMIN_STATUS_DATE" DATE,
"CATEGORY_REGISTR_STATUS" CHAR(25 BYTE),
"CATEGORY_REGISTR_STATUS_DATE" DATE,
"CATEGORY_STATUS" VARCHAR2(10 BYTE),
"CATEGORY_STATUS_JUST" VARCHAR2(2000 BYTE),
"CATEGORY_TYPE" NUMBER
There was some other stuff around the code snippet I sent so I created a new stored procedure where I assigned the values that would be passed as parameters (the variables I set in the debugger). I still get the ORA-01401 on the select count(*) into N line.
The issues goes away when I comment out the where clause.
create or replace PROCEDURE PROCEDURE1
IS
CATEGORY_NAME_EXISTS Exception;
WRONG_ACTION_PARAM Exception;
WRONG_PARAM_SET Exception;
NO_JUSTIFICATION Exception;
VERSION_PERSISTENT Exception;
CANNOT_APPROVE Exception;
VERSION_SETTING_NEEDED Exception;
n number :=1;
msg1 nvarchar2(2000);
curr_status nvarchar2(10);
curr_persistent number;
curr_sett_status nvarchar2(10);
update_with_hierarchy nvarchar2(3);
sql_txt nvarchar2(1000);
err_num number;
err_msg varchar2(200);
CAT_LONG_NAME nvarchar2(1000) := 'Administrative';
CAT_SHORT_NAME nvarchar2(1000) := 'Administrative';
CAT_DESCR nvarchar2(1000) := 'Admin form';
SETT_ID number := 2;
CAT_ID number := 13;
categORy_long_name nvarchar2(1000);
categORy_shORt_name nvarchar2(1000);
categORy_description nvarchar2(1000);
settings_setting_id number;
categORy_id number;
BEGIN
SELECT COUNT(*) INTO n
FROM categORy
WHERE
(
UPPER(LTRIM(RTRIM(categORy_long_name))) = UPPER(LTRIM(RTRIM(cat_long_name)))
OR
UPPER(LTRIM(RTRIM(categORy_shORt_name))) = UPPER(LTRIM(RTRIM(cat_shORt_name)))
OR
UPPER(LTRIM(RTRIM(categORy_description))) = UPPER(LTRIM(RTRIM(cat_descr)))
)
AND (settings_setting_id = sett_id) and (categORy_id <> cat_id)
;
END;
Try this:
DECLARE
n number := 1;
BEGIN
SELECT COUNT(*) INTO n
FROM categORy
WHERE
(
UPPER(LTRIM(RTRIM(categORy_long_name))) = UPPER(LTRIM(RTRIM(cat_long_name)))
OR
UPPER(LTRIM(RTRIM(categORy_shORt_name))) = UPPER(LTRIM(RTRIM(cat_shORt_name)))
OR
UPPER(LTRIM(RTRIM(categORy_description))) = UPPER(LTRIM(RTRIM(cat_descr)))
)
AND (settings_setting_id = sett_id) and (categORy_id <> cat_id);
END;

PL SQL Nested IF ELSE with Cursor

I have three cursors declared CUR_AD1, CUR_AD1_C, CUR_AD_2. All they contain is result coming from a 3 mere select statements which works fine.
Later on I have the following statements:
BEGIN
FOR AD1_REC IN CUR_AD1 LOOP
V_ORG_NAME := AD1_REC.ADDRESS_LINE1;
IF V_ORG_NAME = AD1_REC.ADDRESS_LINE1 THEN
INSERT INTO DSOPI_PERSON_ADDR_RULE
(CCTR_PERSON_ADDRESS_ID, CCTR_PERSON_ID, SRC_ADDRESS_LINE1, SRC_ADDRESS_LINE2, SRC_ADDRESS_LINE3, SRC_ADDRESS_LINE4,
ORG_NAME, DEPT_NAME, TGT_ADDRESS_LINE1, TGT_ADDRESS_LINE2, TGT_ADDRESS_LINE3, TGT_ADDRESS_LINE4,
STATE, CITY, COUNTRY_NAME, ZIP_CODE, EXTRACT_DATE)
VALUES
(AD1_REC.CCTR_PERSON_ADDRESS_ID, AD1_REC.CCTR_PERSON_ID, AD1_REC.ADDRESS_LINE1, AD1_REC.ADDRESS_LINE2, AD1_REC.ADDRESS_LINE3, AD1_REC.ADDRESS_LINE4,
V_ORG_NAME, '', '', AD1_REC.ADDRESS_LINE2, AD1_REC.ADDRESS_LINE3, AD1_REC.ADDRESS_LINE4,
AD1_REC.STATE, AD1_REC.CITY, AD1_REC.COUNTRY_NAME, AD1_REC.ZIP_CODE, SYSDATE);
ELSIF V_ORG_NAME = AD1_REC.ADDRESS_LINE2 THEN
FOR AD2_REC IN CUR_AD2 LOOP
INSERT INTO DSOPI_PERSON_ADDR_RULE
(CCTR_PERSON_ADDRESS_ID, CCTR_PERSON_ID, SRC_ADDRESS_LINE1, SRC_ADDRESS_LINE2, SRC_ADDRESS_LINE3, SRC_ADDRESS_LINE4,
ORG_NAME, DEPT_NAME, TGT_ADDRESS_LINE1, TGT_ADDRESS_LINE2, TGT_ADDRESS_LINE3, TGT_ADDRESS_LINE4,
STATE, CITY, COUNTRY_NAME, ZIP_CODE, EXTRACT_DATE)
VALUES
(AD2_REC.CCTR_PERSON_ADDRESS_ID, AD2_REC.CCTR_PERSON_ID, AD2_REC.ADDRESS_LINE1, AD2_REC.ADDRESS_LINE2, AD2_REC.ADDRESS_LINE3, AD2_REC.ADDRESS_LINE4,
AD2_REC.ADDRESS_LINE2, NULL, AD2_REC.TGT_ADDRESS_LINE1, NULL, AD2_REC.ADDRESS_LINE3, AD2_REC.ADDRESS_LINE4,
AD2_REC.STATE, AD2_REC.CITY, AD2_REC.COUNTRY_NAME, AD2_REC.ZIP_CODE, SYSDATE);
END LOOP;
END IF;
END LOOP;
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR' || SQLERRM);
RAISE;
END;
When I compile the body I keep getting the following errors:
PL/SQL: SQL Statement ignored
PLS-00302: component 'ZIP_CODE' must be declared
PL/SQL: ORA-00984: column not allowed here
There is no problem with the tables whatsoever. I think it has to do something with the how I am putting my control statements. Any help is highly appreciated.
DDL for Table DSOPI_PERSON_ADDR_RULE
CREATE TABLE "CALSEED_OWNER"."DSOPI_PERSON_ADDR_RULE"
( "CCTR_PERSON_ADDRESS_ID" NUMBER(12,0),
"CCTR_PERSON_ID" NUMBER(12,0),
"SRC_ADDRESS_LINE1" VARCHAR2(100 BYTE),
"SRC_ADDRESS_LINE2" VARCHAR2(100 BYTE),
"SRC_ADDRESS_LINE3" VARCHAR2(100 BYTE),
"SRC_ADDRESS_LINE4" VARCHAR2(100 BYTE),
"ORG_NAME" VARCHAR2(100 BYTE),
"DEPT_NAME" VARCHAR2(100 BYTE),
"TGT_ADDRESS_LINE1" VARCHAR2(100 BYTE),
"TGT_ADDRESS_LINE2" VARCHAR2(100 BYTE),
"TGT_ADDRESS_LINE3" VARCHAR2(100 BYTE),
"TGT_ADDRESS_LINE4" VARCHAR2(100 BYTE),
"STATE" VARCHAR2(100 BYTE),
"CITY" VARCHAR2(100 BYTE),
"COUNTRY_NAME" VARCHAR2(100 BYTE),
"ZIP_CODE" VARCHAR2(100 BYTE),
"EXTRACT_DATE" DATE,
"STREET" VARCHAR2(100 BYTE),
"STREET_CONTD" VARCHAR2(100 BYTE)
CURSOR CUR_AD2 IS
SELECT CCTR_PERSON_ADDRESS_ID, 'AL2' AL,ADDRESS_LINE2
FROM STG_RT2_PERSON_ADDRESS WHERE UPPER(ADDRESS_LINE2) IN
( SELECT UPPER(ORG_NAME) FROM STG_RT2_ORGANIZATION
WHERE NOT REGEXP_LIKE(ORG_NAME, '[0-9]')
AND NOT (LOWER(ORG_NAME) LIKE 'unknown' OR LOWER(ORG_NAME) LIKE 'no address%'
OR ORG_NAME ='-' OR ORG_NAME=' '));
For debugging purposes you can use
DBMS_UTILITY.format_error_backtrace;
Make sure all alias in your cursors (not only your table) match the columns you are trying to access e.g.
FOR x IN SELECT zip_code zipCode FROM myTable LOOP
dbms_output.put_line(x.zip_Code)
END LOOP;
The example breaks because x contains zipCode instead of zip_code.
With the information you provided, we can't give any further help, post a describe of your table aswell as your cursors declaration or make a compilable example.
This is useful http://sqlfiddle.com/
Edit
The problem is your cursor declaration
SELECT
CCTR_PERSON_ADDRESS_ID,
'AL2' AL,
ADDRESS_LINE2,
ZIP_CODE -- ADD THIS FOR THE ZIP CODE, YOU NEED TO ADD ALL THE OTHER COLUMNS ASWELL...
FROM
STG_RT2_PERSON_ADDRESS
WHERE
UPPER(ADDRESS_LINE2) IN
(
SELECT
UPPER(ORG_NAME)
FROM
STG_RT2_ORGANIZATION
WHERE
NOT REGEXP_LIKE(ORG_NAME, '[0-9]')
AND NOT
(
LOWER(ORG_NAME) LIKE 'unknown'
OR LOWER(ORG_NAME) LIKE 'no address%'
OR ORG_NAME ='-'
OR ORG_NAME =' '
)
);
Every CUR_AD_2 is a record on your result set, therefore it has its same number of columns and names, in your query, you have only 3 columns but you are trying to access a lot of them (like zip code) that are not in the cursor; make sure to add ZIP_CODE and all the other columns needed. Or just delete them from the INSERT statement
Please check zip_code spelling matchecs column name in the table

ORACLE -1401 error

I have a stored procedure in Oracle 9i which inserts records in a table. The table has a primary key built to ensure duplicte rows doesnot exists.
I am trying to insert a record by calling this stored procedure and it works first time properly. I am again trying to insert a duplicate record and expecting unique constraint violation error. But I am getting
ORA-01401 inserted value too large for column
I knew its meaning but my query is , if the value inserted is really large then how it got successful in the first attempt.
Table is
CREATE TABLE KEY
(
ID VARCHAR2(25 BYTE),
KEY NUMBER(4) NOT NULL,
INSERT_DATE DATE,
WORK_KEY VARCHAR2(128 BYTE)
)
CREATE UNIQUE INDEX SACHINIDX ON KEY
(ID, KEY)
Call is
EXEC SQL EXECUTE
BEGIN
keyadd(:id, :key, :wkey);
END;
END-EXEC;
Stored Procedure is
PROCEDURE keyadd(id IN VARCHAR2, key IN NUMBER, wkey IN VARCHAR2)
{
BEGIN
INSERT INTO KEY
( ID,
KEY,
INSERT_DATE,
WORK_KEY)
VALUES
(
id,
key,
SYSDATE,
wkey
);
EXCEPTION
ROLLBACK;
COMMIT;
RETURN;
END;
}
First insert sqlca.sqlcode is [0]
Second insert sqlca.sqlcode is [-1401]
CREATE TABLE KEY
(
ID VARCHAR2(25 BYTE),
KEY NUMBER(4) NOT NULL,
INSERT_DATE DATE,
WORK_KEY VARCHAR2(128 BYTE)
);
CREATE UNIQUE INDEX SACHINIDX ON KEY
(ID, KEY);
create or replace PROCEDURE keyadd(id IN VARCHAR2, key IN NUMBER, wkey IN VARCHAR2)
is
BEGIN
INSERT INTO KEY
( ID,
KEY,
INSERT_DATE,
WORK_KEY)
VALUES
(
id,
key,
SYSDATE,
wkey
);
COMMIT;
-- EXCEPTION when others then
-- ROLLBACK;
end keyadd;
/
begin
keyadd('one', 1, '59FC9AD0FA5A8932836824B0489B73252C120301A2205154C096B4EB213FA983D5E500B62A469439');
keyadd('one', 1, '905BD61AAEC986ACF887DBA7C04D650B61A8818ABEBE1720D810B4A426EB9220558B530D5119315F');
end;
/
gives me the expected ORA-00001: Unique Constraint... error, not an ORA-01401. So, without further information its impossible to help.
I don't know the language the procedure was written in, but this part:
EXCEPTION
ROLLBACK;
COMMIT;
RETURN;
raises my eyebrows. Two questions:
What is this supposed to do?
Is your issue solved when you remove those lines?
My best guess is on your second try, you are providing a value for one of the other columns that is too large. Looks like this error will supersede the primary key violation.

Resources