How do I execute clob in execute immediate - sql

I have a table with one row and clob as column (whose size is 5239). This column contains a table script extracted with the help of dbms_metadata.get_ddl. Along with table ddl it also extracts the primary key constraint and unique index script.
When I try to execute the script in my plsql block with execute immediate, it throws the following error:
ora-00922: missing or invalid option
Can somebody help me with what might be going wrong?
DECLARE lr_ddl CLOB;
BEGIN
SELECT TEXT INTO lr_ddl FROM DUMMY_1;
EXECUTE IMMEDIATE lr_nvm_ddl;
EXCEPTION WHEN OTHERS
THEN raise_application_error(-20001, chr(10)||' Failed ' || SQLERRM);
END;
Below is the script that I have in clob and I am trying to execute with execute immediate in my anonymous block.
CREATE TABLE abc_PROD.travel_hist
( travel_NO NUMBER NOT NULL ENABLE,
OBJECT_ID VARCHAR2(32) NOT NULL ENABLE,
flight_NO NUMBER,
LIFT_ACCOUNT VARCHAR2(32),
CARR_id VARCHAR2(32),
V_1 NUMBER,
V_2 NUMBER,
V_3 NUMBER,
V_4 NUMBER,
V_5 NUMBER,
V_6 NUMBER,
V_7 NUMBER,
V_8 NUMBER,
V_9 NUMBER,
V_10 NUMBER,
V_11 NUMBER,
V_12 NUMBER,
V_13 NUMBER,
V_14 NUMBER,
V_15 NUMBER,
V_16 NUMBER,
V_17 NUMBER,
V_18 NUMBER,
V_19 NUMBER,
V_20 NUMBER,
V_21 NUMBER,
V_22 NUMBER,
V_23 NUMBER,
V_24 NUMBER,
V_25 NUMBER,
V_26 NUMBER,
V_27 NUMBER,
V_28 NUMBER,
V_29 NUMBER,
V_30 NUMBER,
T_1 VARCHAR2(16),
T_2 VARCHAR2(32),
T_3 VARCHAR2(240),
T_4 VARCHAR2(2000),
T_5 VARCHAR2(240),
T_6 VARCHAR2(240),
T_7 VARCHAR2(240),
T_8 VARCHAR2(240),
T_9 VARCHAR2(240),
T_10 VARCHAR2(240),
T_11 VARCHAR2(2000),
T_12 VARCHAR2(2000),
T_13 VARCHAR2(2000),
T_14 VARCHAR2(2000),
T_15 VARCHAR2(2000),
T_16 VARCHAR2(2000),
T_17 VARCHAR2(2000),
T_18 VARCHAR2(2000),
T_19 VARCHAR2(2000),
T_20 VARCHAR2(2000),
DATE_1 DATE,
DATE_2 DATE,
DATE_3 DATE,
DATE_4 DATE,
DATE_5 DATE,
DATE_6 DATE,
DATE_7 DATE
) ;
CREATE UNIQUE INDEX abc_PROD.PK_TRAVEL ON abc_PROD.travel_hist (travel_NO)
;
ALTER TABLE abc_PROD.travel_hist ADD CONSTRAINT PK_TRAVEL PRIMARY KEY (travel_NO)
USING INDEX abc_PROD.PK_TRAVEL ENABLE;

You could execute those commands one by one in a LOOP. Something like in the code here. I just printed the commands, but you could execute them:
SET SERVEROUTPUT ON
DECLARE
mySQL VarChar2(8000);
mySQLexecute VarChar2(8000);
BEGIN
SELECT TEXT INTO mySQL FROM DUMMY_1;
--
WHILE InStr(mySQL, ';') > 0 LOOP
mySQLexecute := SubStr(mySQL, 1, INSTR(mySQL, ';'));
-- OR mySQLexecute := SubStr(mySQL, 1, INSTR(mySQL, ';')-1); if you want a command without semicolon (;)
DBMS_OUTPUT.PUT_LINE(mySQLexecute);
--EXECUTE IMMEDIATE mySQLexecute;
mySQL := SubStr(mySQL, INSTR(mySQL, ';') + 1);
END LOOP;
EXCEPTION WHEN OTHERS THEN
raise_application_error (-20001, chr(10)||' Failed ' || SQLERRM);
END;

Related

ORA-06502: PL/SQL: numeric or value error by ora_sql_txt

I have table for ddl logs. And in this table I also want to see which code was exactly done. How can I put it into sql_tt column? Can you prompt me with this?
CREATE TABLE AAUDIT_DDL (
d date,
OSUSER varchar2(255),
CURRENT_USER varchar2(255),
HOST varchar2(255),
IP_ADDRESS VARCHAR2(100 CHAR),
TERMINAL varchar2(255),
owner varchar2(30),
OBJECT_TYPE varchar2(30),
OBJECT_NAME varchar2(30),
DDL_TYPE varchar2(30),
SQL_TT varchar(100));
and trigger
create or replace trigger aaudit_ddl after ddl on DATABASE
begin
if (ora_sysevent='REVOKE')
then
null; -- I do not care about REVOKE
else
insert into aaudit_ddl(d, osuser,current_user,host,ip_address,terminal,owner,OBJECT_TYPE,OBJECT_NAME,DDL_TYPE,SQL_TT)
values(
sysdate,
sys_context('USERENV','OS_USER') ,
sys_context('USERENV','CURRENT_USER') ,
sys_context('USERENV','HOST') ,
SYS_CONTEXT('USERENV','IP_ADDRESS'),
sys_context('USERENV','TERMINAL') ,
ora_dict_obj_owner,
ora_dict_obj_type,
ora_dict_obj_name,
ora_sysevent,
ora_sql_txt
);
end if;
end;
/
Documentation suggests different approach to ora_sql_txt: as function expects IN parameter (which is an integer, representing number of elements in PL/SQL table), you should
CREATE TABLE event_table (col VARCHAR2(2030));
DECLARE
sql_text ora_name_list_t;
n PLS_INTEGER;
v_stmt VARCHAR2(2000);
BEGIN
n := ora_sql_txt(sql_text);
FOR i IN 1..n LOOP
v_stmt := v_stmt || sql_text(i);
END LOOP;
INSERT INTO event_table VALUES ('text of triggering statement: ' || v_stmt);
END;
This is how I have mine setup and it works fine.
--Table will be created by sys user with tbs_audit as tablespace as default tablespace for audit table AUDIT_DDL
CREATE TABLE AUDIT_DDL (
DDL_DATE date,
OSUSER varchar2(255),
CURRENT_USER varchar2(255),
HOST varchar2(255),
TERMINAL varchar2(255),
IP_ADDRESS VARCHAR2(100),
module varchar2(100),
owner varchar2(30),
type varchar2(30),
name varchar2(30),
sysevent varchar2(30),
sql_txt varchar2(4000) )
tablespace tbs_audit ;
--- Trigger will be created at sys user, so that all statements will be captured in any schema in the database
create or replace trigger
sys.audit_ddl_trg after ddl on database
declare
sql_text ora_name_list_t;
stmt VARCHAR2(4000) := '';
n number;
begin
n:=ora_sql_txt(sql_text);
for i in 1..n
loop
stmt:=substr(stmt||sql_text(i),1,4000);
end loop;
insert into audit_ddl(
DDL_DATE,osuser,
current_user,host,
terminal,
ip_address,module,
owner,
type,name,sysevent,sql_txt)
values(
sysdate,
sys_context('USERENV','OS_USER') ,
sys_context('USERENV','CURRENT_USER') ,
sys_context('USERENV','HOST') ,
sys_context('USERENV','TERMINAL') ,
UTL_INADDR.get_host_name('USERENV'),
sys_context('USERENV','MODULE') ,
ora_dict_obj_owner,
ora_dict_obj_type,
ora_dict_obj_name,
ora_sysevent,
stmt
);
end;
/
-- Sql Query can be used to lookup the captured ddl in the audit_ddl table.
col type format a10
col name format a10
col host format a16
col IP_ADDRESS format a10
col terminal format a20
col owner format a15
col sql_txt format a20
col SYSEVENT format a10
col CURRENT_USER format a10
col osuser format a10
select * from AUDIT_DDL;

PLS-00103: Encountered the symbol "/"

The error I am receiving depends on whether I remove the "/" or leave it.
With /:
PLS-00103: Encountered the symbol /
Without /:
PLS-00103: Encountered the symbol CREATE
What am I doing wrong?
CREATE OR REPLACE PACKAGE EMP_PACKAGE AS
TYPE EMP_TYPE IS RECORD
( /* Employee Type */
employee_id NUMBER(6,0),
first_name VARCHAR2(20),
last_name VARCHAR2(25),
email VARCHAR2(25),
phone_number VARCHAR2(20),
hire_date DATE,
job_id VARCHAR2(10),
salary NUMBER(6,2),
commission_pct NUMBER(2,2),
manager_id NUMBER(6,0),
department_id NUMBER(4,0)
);
PROCEDURE add_emp(employee_id NUMBER);
PROCEDURE edit_first_name(employee_id NUMBER, first_name employees.first_name%TYPE);
FUNCTION get_emp(employee_id NUMBER) RETURN employee_id;
END;
/
CREATE OR REPLACE PACKAGE BODY EMP_PACKAGE AS
-- procedure will edit an employee's first name
PROCEDURE edit_first_name(employee_id NUMBER) IS
BEGIN
INSERT INTO employees (employees.first_name)
VALUES (first_name);
END edit_first_name;
END;
/
In the package specification you have the line:
FUNCTION get_emp(employee_id NUMBER) RETURN employee_id;
employee_id is not a valid data type.
Once you change that to a valid type then you get to the errors in the package body:
You are missing the ADD_EMP procedure and GET_EMP function.
PROCEDURE edit_first_name(employee_id NUMBER) does not match the declaration in the package specification as its missing the first_name employees.first_name%TYPE argument.
In INSERT INTO employees (employees.first_name) VALUES (first_name); the column is first_name not employees.first_name.
you have some errors in your code.
maybe you need something this?
i compile this in sql developer without any errors
create or replace PACKAGE EMP_PACKAGE AS
TYPE EMP_TYPE IS RECORD
( /* Employee Type */
employee_id NUMBER(6,0),
first_name VARCHAR2(20),
last_name VARCHAR2(25),
email VARCHAR2(25),
phone_number VARCHAR2(20),
hire_date DATE,
job_id VARCHAR2(10),
salary NUMBER(6,2),
commission_pct NUMBER(2,2),
manager_id NUMBER(6,0),
department_id NUMBER(4,0)
);
PROCEDURE add_emp(p_employee_id NUMBER);
PROCEDURE edit_first_name(p_employee_id NUMBER, p_first_name employees.first_name%TYPE);
FUNCTION get_emp(p_employee_id NUMBER) RETURN EMP_TYPE;
END;
/
create or replace PACKAGE BODY EMP_PACKAGE AS
-- procedure will edit an employee's first name
PROCEDURE edit_first_name(p_employee_id NUMBER, p_first_name employees.first_name%TYPE) IS
BEGIN
update employees emp
set emp.first_name = p_first_name
where emp.employee_id = p_employee_id;
END edit_first_name;
PROCEDURE add_emp(p_employee_id NUMBER) IS BEGIN
null;
END;
FUNCTION get_emp(p_employee_id NUMBER) RETURN EMP_TYPE IS
BEGIN
return null;
END;
END;

How can I fix this “SQL Statement ignored” error? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have the following small function that does not compile:
CREATE OR REPLACE PROCEDURE insertarVentas(ID NUMBER, IDCliente NUMBER, nombre VARCHAR2, calle VARCHAR2, poblacion VARCHAR2, cp NUMBER, provincia VARCHAR2, dni VARCHAR2,
telef1 VARCHAR2, telef2 VARCHAR2, telef3 VARCHAR2, fechaventa date, numerolinea NUMBER, IDProducto NUMBER, descripcion VARCHAR2, pvp NUMBER, stockactual NUMBER, cantidad NUMBER) AS
BEGIN
INSERT INTO TABLA_VENTAS VALUES (ID, TIP_CLIENTE(IDCliente, nombre, TIP_DIRECCION(calle, poblacion, cp, provincia), dni, TIP_TELEFONOS(telef1, telef2, telef3)), fechaventa,
TIP_LINEAS_VENTA(numerolinea, TIP_PRODUCTO(IDProducto, descripcion, pvp, stockactual), cantidad));
END insertarVentas;
The compiler gives me the following errors:
Error at line 4: PL/SQL: SQL Statement ignored
2. telef1 VARCHAR2, telef2 VARCHAR2, telef3 VARCHAR2, fechaventa date, numerolinea NUMBER, IDProducto NUMBER, descripcion VARCHAR2, pvp NUMBER, stockactual NUMBER, cantidad NUMBER) AS
3. BEGIN
4. INSERT INTO TABLA_VENTAS VALUES (ID, TIP_CLIENTE(IDCliente, nombre, TIP_DIRECCION(calle, poblacion, cp, provincia), dni, TIP_TELEFONOS(telef1, telef2, telef3)), fechaventa,
5. TIP_LINEAS_VENTA(numerolinea, TIP_PRODUCTO(IDProducto, descripcion, pvp, stockactual), cantidad));
6. END insertarVentas;
This is an insert into a object table, this is the code that table
CREATE TABLE TABLA_VENTAS OF TIP_VENTA(
IDVENTA PRIMARY KEY
)NESTED TABLE LINEAS STORE AS TABLA_LINEAS;
CREATE TYPE TIP_VENTA AS OBJECT(
IDVENTA NUMBER,
IDCLIENTE REF TIP_CLIENTE,
CREATE TYPE TIP_CIENTE AS OBJECT(
IDCLIENTE NUMBER,
NOMBRE VARCHAR2(50),
DIREC TIP_DIRECCION,
CREATE TYPE TIP_DIRECCION AS OBJECT(
CALLE VARCHAR2(50),
POBLACION VARCHAR2(50),
CODPOSTAL NUMBER(5),
PROVINCIA VARCHAR2(40)
);
NIF VARCHAR2(9),
TELEF TIP_TELEFONOS
CREATE TYPE TIP_TELEFONOS AS VARRAY(3) OF VARCHAR2(15);
);
FECHAVENTA DATE,
LINEAS TIP_LINEAS_VENTA,
CREATE TYPE TIP_LINEAVENTA AS OBJECT(
NUMEROLINEA NUMBER,
IDPRODUCTO REF TIP_PRODUCTO,
CREATE TYPE TIP_PRODUCTO AS OBJECT(
IDPRODUCTO NUMBER,
DESCRIPCION VARCHAR2(80),
PVP NUMBER,
STOCKACTUAL NUMBER
);
CANTIDAD NUMBER
);
CREATE TYPE TIP_LINEAS_VENTA AS TABLE OF TIP_LINEAVENTA;
);
What is causing this error and how can I fix it?
The PL/SQL: SQL Statement ignored message is usually just the top of the error stack and a following line will indicate what the actual issue is.
Having untangled your object creation statements and got them in an order that lets them all compile (and fixed at least one typo, and guess that a dangling comma was also a typo), creating your procedure gets:
LINE/COL ERROR
-------- ------------------------------------
4/1 PL/SQL: SQL Statement ignored
4/13 PL/SQL: ORA-00947: not enough values
You've defined TIP_VENTA with five fields:
CREATE TYPE TIP_VENTA AS OBJECT(
IDVENTA NUMBER,
IDCLIENTE REF TIP_CLIENTE,
FECHAVENTA DATE,
LINEAS TIP_LINEAS_VENTA,
CANTIDAD NUMBER
);
But the object you create during your insert only has four values (reformatted to make it a bit more readable):
INSERT INTO TABLA_VENTAS VALUES (
ID,
TIP_CLIENTE(
IDCliente,
nombre,
TIP_DIRECCION(calle, poblacion, cp, provincia),
dni,
TIP_TELEFONOS(telef1, telef2, telef3)
),
fechaventa,
TIP_LINEAS_VENTA(
numerolinea,
TIP_PRODUCTO(IDProducto, descripcion, pvp, stockactual),
cantidad
)
);
You've got cantidad inside the TIP_LINEAS_VENTA() constructor call, instead of after it:
INSERT INTO TABLA_VENTAS VALUES (
ID,
TIP_CLIENTE(
IDCliente,
nombre,
TIP_DIRECCION(calle, poblacion, cp, provincia),
dni,
TIP_TELEFONOS(telef1, telef2, telef3)
),
fechaventa,
TIP_LINEAS_VENTA(
numerolinea,
TIP_PRODUCTO(IDProducto, descripcion, pvp, stockactual)
),
cantidad
);
But that now gets:
LINE/COL ERROR
-------- ------------------------------------------------------------------
9/1 PL/SQL: SQL Statement ignored
20/5 PL/SQL: ORA-00932: inconsistent datatypes: expected UDT got NUMBER
The fourth field of the TIP_VENTA is type TIP_LINEAS_VENTA, so you need to have a TIP_LINEAVENTA within that table constructor:
TIP_LINEAS_VENTA(
TIP_LINEAVENTA(
numerolinea,
TIP_PRODUCTO(IDProducto, descripcion, pvp, stockactual)
)
Which then gets:
LINE/COL ERROR
-------- -----------------------------------------------------------------------------------------------------------------
9/1 PL/SQL: SQL Statement ignored
22/7 PL/SQL: ORA-00932: inconsistent datatypes: expected X.TIP_PRODUCTO got REF X.TIP_PRODUCTO
... because you're using actual objects instead of REFs to them, as the other type definitions expect. You'll need to decide whether to make them actual objects or fix the REFs...
I think the issue is that you're trying to insert into a table of an object something that isn't an object.
I've split out your object type populations into variables (rather than leaving them nested inside the insert statement as you did) which hopefully enables you to see what it is you're actually trying to insert:
create or replace procedure insertarventas (id number,
idcliente number,
nombre varchar2,
calle varchar2,
poblacion varchar2,
cp number,
provincia varchar2,
dni varchar2,
telef1 varchar2,
telef2 varchar2,
telef3 varchar2,
fechaventa date,
numerolinea number,
idproducto number,
descripcion varchar2,
pvp number,
stockactual number,
cantidad number)
as
v_tip_venta tip_venta;
v_tip_cliente tip_cliente;
v_tip_direccion tip_direccion;
v_tip_telefonos tip_telefonos;
v_tip_lineaventa tip_lineaventa;
v_tip_lineas_venta tip_lineas_venta;
v_tip_producto tip_producto;
begin
v_tip_direccion := tip_direccion (calle,
poblacion,
cp,
provincia);
v_tip_telefonos := tip_telefonos (telef1,
telef2,
telef3);
v_tip_cliente := tip_cliente (idcliente,
nombre,
v_tip_direccion,
dni,
v_tip_telefonos);
v_tip_producto := tip_producto (idproducto,
descripcion,
pvp,
stockactual);
v_tip_lineaventa := tip_lineaventa (numerolinea,
v_tip_producto,
cantidad);
v_tip_lineas_venta := tip_lineas_venta (v_tip_lineaventa);
-- this is the step you were missing
v_tip_venta := tip_venta (id,
v_tip_cliente,
fechaventa,
v_tip_lineas_venta);
insert into tabla_ventas
values (v_tip_venta);
end insertarventas;
/
N.B. untested.
Ok, the presence of the REFs in the object type descriptions is what is causing the problems. However, I don't think it's necessary to use REF (not to mention that I couldn't work out how to make the code work with them! *{;-) ), so here is a working test case without the REFs:
drop procedure insertarventas;
drop table tabla_ventas;
drop type tip_venta;
drop type tip_lineas_venta;
drop type tip_lineaventa;
drop type tip_producto;
drop type tip_cliente;
drop type tip_telefonos;
drop type tip_direccion;
create type tip_direccion as object (calle varchar2(50),
poblacion varchar2(50),
codpostal number(5),
provincia varchar2(40));
create type tip_telefonos as varray(3) of varchar2(15);
create type tip_cliente as object (idcliente number,
nombre varchar2(50),
direc tip_direccion,
nif varchar2(9),
telef tip_telefonos);
create type tip_producto as object (idproducto number,
descripcion varchar2(80),
pvp number,
stockactual number);
create type tip_lineaventa as object (numerolinea number,
idproducto tip_producto,
cantidad number);
create type tip_lineas_venta as table of tip_lineaventa;
create type tip_venta as object (idventa number,
idcliente tip_cliente,
fechaventa date,
lineas tip_lineas_venta);
create table tabla_ventas of tip_venta (idventa primary key)
nested table lineas store as tabla_lineas;
create or replace procedure insertarventas (id number,
idcliente number,
nombre varchar2,
calle varchar2,
poblacion varchar2,
cp number,
provincia varchar2,
dni varchar2,
telef1 varchar2,
telef2 varchar2,
telef3 varchar2,
fechaventa date,
numerolinea number,
idproducto number,
descripcion varchar2,
pvp number,
stockactual number,
cantidad number)
as
v_tip_venta tip_venta;
v_tip_cliente tip_cliente;
v_tip_direccion tip_direccion;
v_tip_telefonos tip_telefonos;
v_tip_lineaventa tip_lineaventa;
v_tip_lineas_venta tip_lineas_venta;
v_tip_producto tip_producto;
begin
v_tip_direccion := tip_direccion (calle,
poblacion,
cp,
provincia);
v_tip_telefonos := tip_telefonos (telef1,
telef2,
telef3);
v_tip_cliente := tip_cliente (idcliente,
nombre,
v_tip_direccion,
dni,
v_tip_telefonos);
v_tip_producto := tip_producto (idproducto,
descripcion,
pvp,
stockactual);
v_tip_lineaventa := tip_lineaventa (numerolinea,
v_tip_producto,
cantidad);
v_tip_lineas_venta := tip_lineas_venta (v_tip_lineaventa);
-- this is the step you were missing
v_tip_venta := tip_venta (id,
v_tip_cliente,
fechaventa,
v_tip_lineas_venta);
insert into tabla_ventas
values (v_tip_venta);
end insertarventas;
/

Error: numeric or value errors

I know this error issue was been addressed before, but I can't seem to find any relevant solution so I'm posting this question.
create table subscribers(
num_s number(6,0) ,
name varchar2(30) constraint nameM not null,
surname varchar2(20),
town varchar2(30),
age number(3,0) ,
rate number(3,0) ,
reduc number(3,0) ,
CONSTRAINT subscriber_pk primary key (num_s),
constraint age_c check (age between 0 and 120)
);
create or replace type copy_bookT as object(
num number(6),
loancode varchar2 (10),
book_ref ref bookT
);
create table copy_books of copy_bookT(
constraint pk_cb primary key (num),
constraint chk_st check (loancode in('Loan', 'Not')),
loancode default 'Loan' not null
);
create table Lending(
cb_num number(6),
sb_num number(6),
date_L date,
constraint fk_cb foreign key (cb_num) references copy_books(num),
constraint fk_sb foreign key (sb_num) references Subscribers(num_s)
);
create or replace trigger chk_DateL
for insert or update on lending
COMPOUND TRIGGER
--declare
L_Date int;
avail varchar2(10);
subtype copy_booksRec is lending%ROWTYPE;
type copied_bks is table of copy_booksRec;
cbks copied_bks := copied_bks();
before each row is
begin
cbks.extend;
cbks(cbks.last).cb_num := :new.cb_num;
cbks(cbks.last).sb_num := :new.sb_num;
end before each row;
before statement is
begin
for i in cbks.first .. cbks.last loop
select loancode into avail from copy_books where num = cbks(i).cb_num;
select count(date_L) into L_Date from lending where sb_num = cbks(i).sb_num and date_L = cbks(i).date_L;
if (L_Date = 0 and avail = 'Loan') then
update copy_books set loancode = 'Not' where num = cbks(i).cb_num;
cbks.delete;
-- cbks(i).date_L := cbks(i).date_L;
else
dbms_output.put_line('You can only make ONE LOAN at a time! You have already loaned a book on ' || L_Date);
cbks.delete;
end if;
end loop;
-- FORALL i IN cbks.first .. cbks.last
-- insert into lending values cbks(i);
cbks.delete;
end before statement;
end chk_DateL;
/
show errors
It all compiles successfully, but when I try to insert a sample record like:
insert into lending values (2, 700, '10-MAR-14');
it raises a numeric error which comes from the trigger line 18. I don't know what needs fixing despite my efforts.
You should not count on Oracle's default date format to translate your string literal to a date value , you should define the format you're using explicitly:
insert into lending values (2, 700, to_date('10-MAR-14', 'DD-MON-YY'));
While the date format issue is a valid point, that isn't causing your error. It's coming from line 18, which is the for ... loop line:
before statement is
begin
for i in cbks.first .. cbks.last loop
You've got cbks being extended and populated from the before row part of the trigger. When the before statement part fires, cbks is empty, as the row-level trigger hasn't fired yet. It's the first and last references that are throwing the ORA-06502: PL/SQL: numeric or value error error.
You can demonstrate the same thing with a simple anonymous block:
declare
type my_type is table of dual%rowtype;
my_tab my_type := my_type();
begin
for i in my_tab.first .. my_tab.last loop
null;
end loop;
end;
/
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 5
SQL Fiddle; you can see you can avoid it by adding an extend, but that doesn't really help you in your version, since you seem to want the row values. (You can eliminate the error in your code with an extend, but it's unlikely to do what you want still).
I'm really not sure what you're trying to achieve here, so I don't really have any advice on what you need to do differently.
as Mureinik already told, Oracle does not know about how to transform your varchar2 into date datatype and you should use date explicitly. But instead of making to_date use date literal - in my opinion it is more clear than using of to_date function
insert into lending values (2,700,date '2014-03-10');
by the way, you can simply change your NLS settings by altering the current session and installing the date format you need

Oracle trigger conflict with null

First and foremost, this is for an assignment, so most of the really cool pre-written functions you'll want to suggest, I will not be allowed to use.
I have a couple tables that all have fields
creation_date
created_by
last_update_date
last_updated_by
I need to write a trigger that fills these in for creation or updating. The problem is, these tables have null values that are problematic to me. Example:
CREATE TABLE parts
(
pno NUMBER,
pname VARCHAR2(50) NOT NULL,
qoh NUMBER NOT NULL,
price NUMBER(5,2),
reorder_level NUMBER(2),
creation_date DATE NOT NULL,
created_by VARCHAR2(10) NOT NULL,
last_update_date DATE NOT NULL,
last_updated_by VARCHAR2(10) NOT NULL,
CONSTRAINT parts_PK PRIMARY KEY (pno))
These NOT NULL's are given to me and I'm not allowed to change them. So I'm having trouble conceptualizing this.
If my trigger adds these values before the field is created, I can't do an INSERT INTO with those fields blank because they're NOT NULL.
If my trigger adds these values after the field is created, I get compilation errors ORA-00903 and 00922. Invalid table name and invalid option.
I was thinking my trigger would look like
CREATE OR REPLACE TRIGGER pcreate
BEFORE UPDATE on parts
FOR EACH ROW
BEGIN
UPDATE
SET creation_date = SYSDATE;
SET created_by = USER;
SET last_update_date = SYSDATE;
SET last_updated_by = USER;
END;
/
CREATE OR REPLACE TRIGGER pchange
BEFORE UPDATE on parts
FOR EACH ROW
BEGIN
UPDATE
SET last_update_date = SYSDATE;
SET last_updated_by = USER;
END;
/
repeat for the other tables
I might be allowed to use UPSERT but I don't really know how that works.. Any suggestions are welcome. I'm really in this to learn so any other advice is appreciated.
EDIT:
My package that will not acknowledge the trigger is as follows. Do I need to call the trigger inside the package?
CREATE OR REPLACE PACKAGE process_orders
AS
PROCEDURE add_order (p_cno IN NUMBER, p_eno IN NUMBER, p_received IN DATE);
PROCEDURE add_order_details (p_ono IN NUMBER, p_pno IN NUMBER, p_qty IN NUMBER);
PROCEDURE ship_order (p_ono IN NUMBER, p_sdate IN DATE);
PROCEDURE delete_order (p_ono IN NUMBER);
FUNCTION total_emp_sales (f_eno IN NUMBER) RETURN NUMBER;
END process_orders;
/
CREATE OR REPLACE PACKAGE BODY process_orders
AS
PROCEDURE add_order (p_cno IN NUMBER, p_eno IN NUMBER, p_received IN DATE)
IS
ao_emsg VARCHAR2(100);
p_rec_today DATE;
BEGIN
SELECT SYSDATE INTO p_rec_today FROM dual;
IF p_received is null THEN
INSERT INTO orders (ono, cno, eno, received)
VALUES(order_number_seq.NEXTVAL,p_cno,p_eno,p_rec_today);
ELSE
INSERT INTO orders (ono, cno, eno, received)
VALUES(order_number_seq.NEXTVAL,p_cno,p_eno,p_received);
END IF;
EXCEPTION
WHEN OTHERS THEN
ao_emsg := substr(SQLERRM,1,100);
INSERT INTO orders_errors (ono,transaction_date,message)
VALUES(order_number_seq.CURRVAL,SYSDATE,ao_emsg);
END;
--Etc. Procedures
END;
/
In your trigger, you simply want to modify the :new record. Your triggers would look something like
CREATE OR REPLACE TRIGGER parts_before_insert
BEFORE INSERT on parts
FOR EACH ROW
BEGIN
:new.creation_date := SYSDATE;
:new.created_by := USER;
:new.last_update_date := SYSDATE;
:new.last_updated_by := USER;
END;
and
CREATE OR REPLACE TRIGGER parts_before_update
BEFORE UPDATE on parts
FOR EACH ROW
BEGIN
:new.last_update_date := SYSDATE;
:new.last_updated_by := USER;
END;
In your INSERT statement, you would omit these four columns and let the trigger fill in the values. For example (obviously, your primary keys would be coming from something like a sequence rather than being hard-coded)
SQL> insert into parts( pno, pname, qoh, price, reorder_level )
2 values( 1, 'Widget', 10, 100, 75 );
1 row created.
SQL> select *
2 from parts;
PNO PNAME QOH
---------- -------------------------------------------------- ----------
PRICE REORDER_LEVEL CREATION_ CREATED_BY LAST_UPDA LAST_UPDAT
---------- ------------- --------- ---------- --------- ----------
1 Widget 10
100 75 26-SEP-12 SCOTT 26-SEP-12 SCOTT
There is no need of executing UPDATE statement in triggers in your case. Just assign new values to the columns using :new.
CREATE OR REPLACE TRIGGER pchange
BEFORE UPDATE on parts
FOR EACH ROW
BEGIN
:new.last_update_date = SYSDATE;
:new.last_updated_by = USER;
END;