Related
I am facing this error while creating a trigger.
error - Error(20,56): PLS-00049: bad bind variable 'NEW.NEW_NAME'
if anyone can help it will be appreciated.
Please refer to my code below
Thanks in Advance :)
CREATE OR REPLACE TRIGGER insert_update_delete_employees AFTER
INSERT OR UPDATE OR DELETE ON employees
REFERENCING
OLD AS old
NEW AS new
FOR EACH ROW
ENABLE DECLARE
v_user VARCHAR2(20);
v_count NUMBER;
v_date VARCHAR2(20);
BEGIN
SELECT
user,
to_date(sysdate, 'DD/MON/YYYY HH24:MI:SS')
INTO
v_user,
v_date
FROM
dual;
SELECT
COUNT(1)
INTO v_count
FROM
employees;
IF updating THEN
INSERT INTO audit_table (
table_name,
user_name,
event,
event_date,
table_count,
new_object_name,
old_object_name
) VALUES (
'EMPLOYEES',
v_user,
'UPDATE',
v_date,
v_count,
:new.new_name,
NULL
);
dbms_output.put_line('Table data has been update by user ' || v_user);
SELECT
COUNT(*)
INTO v_count
FROM
employees;
ELSIF inserting THEN
INSERT INTO audit_table (
table_name,
user_name,
event,
event_date,
table_count,
new_object_name,
old_object_name
) VALUES (
'EMPLOYEES',
v_user,
'INSERT',
v_date,
v_count,
:new.new_name,
:old.old_name
);
dbms_output.put_line('Table data has been inserted by user ' || v_user);
SELECT
COUNT(*)
INTO v_count
FROM
employees;
ELSIF deleting THEN
INSERT INTO audit_table (
table_name,
user_name,
event,
event_date,
table_count,
new_object_name,
old_object_name
) VALUES (
'EMPLOYEES',
v_user,
'DELETE',
v_date,
v_count,
NULL,
:old.old_name
);
dbms_output.put_line('Table data has been deleted by user ' || v_user);
SELECT
COUNT(*)
INTO v_count
FROM
employees;`enter code here`
END IF;
END;
As you are using sample database schema, So please use :new.first_name column instead of :new.new_name
It seems that my procedure does not accept the value which I am trying to insert into the customer table. But why? What is wrong with the cust_id column?
BEGIN
do_new_customer('650707-1111', 'Tito', 'Ortiz', 'qwerTY');
do_new_customer('560126-1148', 'Margreth', 'Andersson', 'olle85');
do_new_customer('840317-1457', 'Mary', 'Smith', 'asdfgh');
do_new_customer('861124-4478', 'Vincent', 'Ortiz', 'qwe123');
COMMIT;
END;
This is my procedure:
create or REPLACE procedure do_new_customer
(p_cust_id in varchar2,
p_first_name in varchar2,
P_last_name in varchar2,
P_passwd in varchar2)
as
v_cust_id number(6);
begin
insert into Customer (cust_id, first_name, last_name, passwd)
values (v_cust_id, P_First_name, P_Last_name, P_passwd);
Commit;
end;
The value is null: I think you forgot the step of converting p_cust_id to a number and storing it in v_cust_id
create or REPLACE procedure do_new_customer
(p_cust_id in varchar2, p_first_name in varchar2, P_last_name in varchar2, P_passwd in varchar2)
as
--YOU DIDN'T SET THIS TO A VALUE SO IT'S NULL
v_cust_id number(6);
begin
insert into Customer( cust_id, first_name, last_name, passwd)
--STILL NULL WHEN YOU CAME TO USE IT
values(v_cust_id, P_First_name,P_Last_name,P_passwd);
Commit;
end;
Try putting SET v_cust_id = p_cust_id::int; or similar operation to cast the varchar to something big numeric, and give v_cust_num a value?
Or as Tim says, pass it directly as p_cust_id, let Postgres figure out the conversion.
Or make p_cust_id match the type of the column in the table and get rid of v_cust_id all together
the variable v_cust_id is not set for the Insert Operation but defined that why you get null.
What you surely want to do is to insert p_cust_id into the customer Table so
instead this :
insert into Customer (cust_id, first_name, last_name, passwd)
values (v_cust_id, P_First_name, P_Last_name, P_passwd);
rewrite the insert:
insert into Customer (cust_id, first_name, last_name, passwd)
values (P_cust_id, P_First_name, P_Last_name, P_passwd);
The fonction will be :
create or REPLACE procedure do_new_customer
(p_cust_id in varchar2,
p_first_name in varchar2,
P_last_name in varchar2,
P_passwd in varchar2)
as
v_cust_id number(6);
begin
insert into Customer (cust_id, first_name, last_name, passwd)
values (P_cust_id, P_First_name, P_Last_name, P_passwd);
Commit;
end;
I think the issue here is that you are passing v_cust_id as the cust_id column value, yet this value does not get defined anywhere. I don't see any reason why you aren't just using all the inputs in the VALUES clause:
CREATE OR REPLACE PROCEDURE do_new_customer (p_cust_id IN VARCHAR2,
p_first_name IN VARCHAR2, P_last_name IN VARCHAR2, P_passwd IN VARCHAR2)
AS
BEGIN
INSERT INTO Customer (cust_id, first_name, last_name, passwd)
VALUES
(p_cust_id, p_first_name, P_last_name, P_passwd);
COMMIT;
END;
create or REPLACE procedure do_new_customer
(p_cust_id in varchar2,
p_first_name in varchar2,
P_last_name in varchar2,
P_passwd in varchar2)
as
v_cust_id number(6);
begin
insert into Customer values (p_cust_id, P_First_name, P_Last_name, P_passwd);
Commit;
end;
-- there is no use of this variable- 'v_cust_id number(6)';
-- create procedure as-
CREATE OR REPLACE PROCEDURE do_new_customer
(
p_cust_id IN VARCHAR2,
p_first_name IN VARCHAR2,
P_last_name IN VARCHAR2,
P_passwd IN VARCHAR2
)
AS
BEGIN
INSERT INTO Customer (cust_id, first_name, last_name, passwd)
VALUES (p_cust_id, p_first_name, P_last_name, P_passwd);
COMMIT;
END;
So I currently have a stored procedure that does a simple insert into a table called 'VALUE'. I tested this piece and called the procedure below:
Create Or Replace Procedure TEST_PROCEDURE(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
BEGIN
IF rValue_Tx >= 0 THEN
IF rData_Type in ('TEST', 'REAL')
THEN
Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
VALUES (1, rValue_tx, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE;
However; when i try to insert a number into a variable (adding another layer of complexity), nothing gets inserted. Below is code with another layer of complexity added to it:
Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
v_MAX_historic_value value.value_tx%type;
BEGIN
---
SELECT MAX(BUFFER_MAX)
INTO v_MAX_Historic_Value
FROM max_look_up;
EXCEPTION
WHEN no_data_found
THEN SELECT 0
INTO v_MAX_Historic_Value
FROM DUAL;
---
IF rValue_Tx >= 0
THEN
IF rData_Type in ('TEST', 'REAL')
THEN
Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
VALUES (null, rValue_tx, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE_NEW;
I am sure I am missing some fundamental rule of PL/SQL but can't seem to figure out which rule. It seems that it's the EXCEPTION that is causing the procedure not to insert any rows into the VALUE table, but I am not exactly sure why (or is there a better way to do this?)... any help would be greatly appreciated :(
Instead of using an EXCEPTION; is there a better way for me to handle when there is no data in max_look_up and nothing/null gets returned as a result?
With some proper code indenting it is obvious that all code except for the first SELECT statement is in the exception handler.
However, SELECT MAX(...) will always return data and never trigger the NO_DATA_FOUND exception. Therefore, the INSERT statement is never reached.
Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
v_MAX_historic_value value.value_tx%type;
BEGIN
SELECT MAX(BUFFER_MAX)
INTO v_MAX_Historic_Value
FROM max_look_up;
EXCEPTION
WHEN no_data_found
THEN
SELECT 0
INTO v_MAX_Historic_Value
FROM DUAL;
IF rValue_Tx >= 0 THEN
IF rData_Type in ('TEST', 'REAL') THEN
Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
VALUES (null, rValue_tx, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE_NEW;
What you probably want is to move the code out of the exception handler. You would do this by introducing another pair of BEGIN / END around the first SELECT statement and the exception handling code. However, since the exception is never triggered, it's easier to remove the exception handling altogether. Instead, you should check for NULL as MAX(...) returns NULL if no rows are selected.
Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
v_MAX_historic_value value.value_tx%type;
BEGIN
SELECT MAX(BUFFER_MAX)
INTO v_MAX_Historic_Value
FROM max_look_up;
IF v_MAX_Historic_Value IS NULL THEN
v_MAX_Historic_Value := 0;
END IF;
...
IF rValue_Tx >= 0 THEN
IF rData_Type in ('TEST', 'REAL') THEN
Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
VALUES (null, rValue_tx, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE_NEW;
I think you only misplaced Exception keyword, try this:
CREATE OR REPLACE PROCEDURE TEST_PROCEDURE_NEW (
RVALUE_TX IN VARCHAR,
RDATA_TYPE IN VARCHAR
)
IS
V_MAX_HISTORIC_VALUE VALUE.VALUE_TX%TYPE;
BEGIN
---
BEGIN
SELECT MAX (BUFFER_MAX) INTO V_MAX_HISTORIC_VALUE FROM MAX_LOOK_UP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
SELECT 0 INTO V_MAX_HISTORIC_VALUE FROM DUAL;
END;
---
IF RVALUE_TX >= 0
THEN
IF RDATA_TYPE IN ('TEST', 'REAL')
THEN
INSERT INTO VALUE (VALUE_ID, VALUE_TX, CREATE_DT)
VALUES (NULL, RVALUE_TX, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE_NEW;
After some further research I found an alternate solution (without the use of exceptions) to my question (please correct me if I'm wrong):
Create Or Replace Procedure TEST_PROCEDURE_NEW(rValue_tx IN VARCHAR, rData_Type IN VARCHAR)
IS
v_MAX_historic_value value.value_tx%type;
BEGIN
with EXEC as
(select 0 buffer_max
from dual
UNION
select MAX(BUFFER_MAX)
FROM max_look_up) select max(buffer_max) into v_MAX_Historic_Value from EXEC;
IF rValue_Tx >= 0 THEN
IF rData_Type in ('TEST', 'REAL') THEN
Insert into Value (VALUE_ID, VALUE_TX, CREATE_DT)
VALUES (null, rValue_tx, SYSDATE);
END IF;
END IF;
END TEST_PROCEDURE_NEW;
Hi stack overflow i am new to sql and im trying to create a procedure to add in new consultant. i will be re using the code in a apex application with a button to Execute the task. Also I have implemented sequence to add to new entry of consultant. Unfortunately I have the error
Compilation failed,line 10 (11:48:18)
PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following: ; is with authid as cluster order using external deterministic parallel_enable pipelined result_cache accessible
could i get some guidance to address this issue as im new to sql thanks guys and research is not helping.
original code
create or replace procedure hirecst
(CST_NAME VARCHAR2,
START_DATE DATE,
LEAVE_DATE DATE,
LOCATION VARCHAR2,
SPECIALIST_AREA VARCHAR2)
RETURN NUMBER IS
new_cst NUMBER;
BEGIN
SELECT CONSULTANT_IDSEQ.NEXTVAL
INTO new_cst
FROM DUAL;
INSERT INTO LDS_CONSULTANT (CONSULTANT_ID, CST_NAME, START_DATE, LEAVE_DATE, LOCATION, SPECIALIST_AREA)
VALUES (new_cst, p_con_name, p_con_start, p_con_end, p_con_loc, p_con_spec);
RETURN(new_cst);
END;
removed the return
create or replace procedure hirecst
(CST_NAME VARCHAR2,
START_DATE DATE,
LEAVE_DATE DATE,
LOCATION VARCHAR2,
SPECIALIST_AREA VARCHAR2)
BEGIN
new_cst NUMBER;
SELECT CONSULTANT_IDSEQ.NEXTVAL
INTO new_cst
FROM DUAL;
INSERT INTO LDS_CONSULTANT (CONSULTANT_ID, CST_NAME, START_DATE, LEAVE_DATE, LOCATION, SPECIALIST_AREA)
VALUES (new_cst, p_con_name, p_con_start, p_con_end, p_con_loc, p_con_spec);
END;
Note: I am ignoring the apparent mismatch between the declared parameter names and the ones used in the INSERT statement.
As documented in the manual you need the AS (or IS) keyword that starts the actual procedure part - after which the variable declaration needs to be written:
create or replace procedure hirecst
(CST_NAME VARCHAR2,
START_DATE DATE,
LEAVE_DATE DATE,
LOCATION VARCHAR2,
SPECIALIST_AREA VARCHAR2)
AS --<< HERE
new_cst NUMBER;
BEGIN
SELECT CONSULTANT_IDSEQ.NEXTVAL
INTO new_cst
FROM DUAL;
INSERT INTO LDS_CONSULTANT
(CONSULTANT_ID, CST_NAME, START_DATE, LEAVE_DATE, LOCATION, SPECIALIST_AREA)
VALUES
(new_cst, p_con_name, p_con_start, p_con_end, p_con_loc, p_con_spec);
END;
However, the SELECT INTO is not required at all, you can use nextval directly in the INSERT statement. So you can simplify the procedure to:
create or replace procedure hirecst
(CST_NAME VARCHAR2,
START_DATE DATE,
LEAVE_DATE DATE,
LOCATION VARCHAR2,
SPECIALIST_AREA VARCHAR2)
AS --<< Still needed!
BEGIN
INSERT INTO LDS_CONSULTANT
(CONSULTANT_ID, CST_NAME, START_DATE, LEAVE_DATE, LOCATION, SPECIALIST_AREA)
VALUES
(CONSULTANT_IDSEQ.NEXTVAL, p_con_name, p_con_start, p_con_end, p_con_loc, p_con_spec);
END;
If you want to return the generated ID from the procedure you need an OUT parameter:
create or replace procedure hirecst
(CST_NAME VARCHAR2,
START_DATE DATE,
LEAVE_DATE DATE,
LOCATION VARCHAR2,
SPECIALIST_AREA VARCHAR2,
p_consultant_id out integer) --<< HERE
AS
BEGIN
-- Assign the value to the OUT parameter
p_consultant_id := CONSULTANT_IDSEQ.NEXTVAL;
INSERT INTO LDS_CONSULTANT
(CONSULTANT_ID, CST_NAME, START_DATE, LEAVE_DATE, LOCATION, SPECIALIST_AREA)
VALUES
(p_consultant_id, p_con_name, p_con_start, p_con_end, p_con_loc, p_con_spec);
END;
/
Following is the syntax of procedre-
CREATE [OR REPLACE] PROCEDURE procedure_name
[ (parameter [,parameter]) ]
IS
[declaration_section]
BEGIN
executable_section
[EXCEPTION
exception_section]
END [procedure_name];
And you forget 'IS' keyword
following is the code-
create or replace procedure hirecst
(CST_NAME VARCHAR2,
START_DATE DATE,
LEAVE_DATE DATE,
LOCATION VARCHAR2,
SPECIALIST_AREA VARCHAR2)
IS
new_cst NUMBER;
begin
SELECT CONSULTANT_IDSEQ.NEXTVAL
INTO new_cst
FROM DUAL;
INSERT INTO LDS_CONSULTANT (CONSULTANT_ID, CST_NAME, START_DATE, LEAVE_DATE, LOCATION, SPECIALIST_AREA)
VALUES (new_cst, p_con_name, p_con_start, p_con_end, p_con_loc, p_con_spec);
end;
;
I have below requirement-
I have 2 tables Main Table A ,Staging table B
I have written a before insert trigger on main table A to check some wrong data. If the data is wrong then it will insert into staging table B so that user can view the errors and correct then and then again upload the data.
My issue is -Data is not getting inserted into staging table as I am using raise_form_trigger_failure just after insert statement.Is there any other way to do this?
TRIGGER CODE-
create or replace trigger CCM_TEST
before insert OR UPDATE ON "CCM_MANAGER"
for each row
declare
l_user varchar2(500);
v_user number;
v_cost_centre number;
v_company_code number;
v_show_error varchar2(100);
begin
l_user := NVL(v('APP_USER'), user);
if inserting then
begin
select count(1)
into v_cost_centre
From gl_code_combinations
where segment2=:new.cost_center
and enabled_flag ='Y';
if (v_cost_centre= 0) then
v_show_error:='Cost Centre does not exists!! '||'Cost Centre -'||:new.cost_center;
:new.CHECK_INSERT_FLAG:='Y';
Insert into CCM_MANAGER_STG(COMPANY_CODE,
COST_CENTER,
USER_NAME,
EFFECTIVE_START_DATE,
EFFECTIVE_END_DATE,
CREATED_BY,
CREATION_DATE,
LAST_UPDATED_BY,
LAST_UPDATE_DATE,
LINE_ID,
CHECK_INSERT_FLAG,
SHOW_ERRORS) values
( :new.COMPANY_CODE,
:new.COST_CENTER,
:new.USER_NAME,
:new.EFFECTIVE_START_DATE,
:new.EFFECTIVE_END_DATE,
:new.CREATED_BY,
:new.CREATION_DATE,
:new.LAST_UPDATED_BY,
:new.LAST_UPDATE_DATE,
:new.LINE_ID,
:new.CHECK_INSERT_FLAG,
v_show_error);
end if;
raise_application_error (-20001, 'Cost Centre does not exists!! '||'Cost Centre -'||:new.cost_center||' ');
exception
when others then
--raise_application_error (-20001, sqlerrm);
null;
end;
begin
select count(1)
into v_company_code
From gl_code_combinations
where segment1=:new.company_code
and enabled_flag ='Y';
if (v_company_code= 0) then
v_show_error:='Company Code does not exists!!';
:new.CHECK_INSERT_FLAG:='Y';
Insert into CCM_MANAGER_STG(COMPANY_CODE,
COST_CENTER,
USER_NAME,
EFFECTIVE_START_DATE,
EFFECTIVE_END_DATE,
CREATED_BY,
CREATION_DATE,
LAST_UPDATED_BY,
LAST_UPDATE_DATE,
LINE_ID,
CHECK_INSERT_FLAG,
SHOW_ERRORS) values
( :new.COMPANY_CODE,
:new.COST_CENTER,
:new.USER_NAME,
:new.EFFECTIVE_START_DATE,
:new.EFFECTIVE_END_DATE,
:new.CREATED_BY,
:new.CREATION_DATE,
:new.LAST_UPDATED_BY,
:new.LAST_UPDATE_DATE,
:new.LINE_ID,
:new.CHECK_INSERT_FLAG,
v_show_error);
end if;
raise_application_error (-20001, 'Company Code does not exists!! '||'Company code -'||:new.company_code||' ');
-- Rollback;
exception
when others then
raise_application_error (-20001, sqlerrm);
null;
end;
end if;
end;
First way is autonomous transaction.
Second way is compound trigger.