This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Autoincrement in Oracle
I have a table in oracle and I want to make userid auto increment..
Once I make it auto increment by using sequence and try to insert into table using procedure where do i put my sample.seq_userid
How do i insert userid? do i have to declare it in my procedure?
PROCEDURE insertExample
(
name_in IN sample.name%TYPE,
age_in IN sample.age%TYPE
)
IS
BEGIN
INSERT INTO sample
(name, age)
VALUES
(name_in, age_in);
END insertExample;
here is my update one
PROCEDURE updateExample
(
userid_in IN sample.userid%TYPE,
name_in IN sample.name%TYPE,
age_in IN sample.age%TYPE
)
IS
BEGIN
UPDATE sample
SET name = name_in,
age = age_in
WHERE userid = userid_in;
END updateExample;
you need a sequence:
create sequence seq_user_id start with 1 increment by 1;
and a trigger on a table
CREATE TRIGGER user_id_trg
BEFORE insert
ON sample
FOR EACH ROW
BEGIN
SELECT seq_user_id.NEXTVAL INTO :new.user_id FROM dual;
END;
/
Related
Please anyone can assist me. I have a table type object.
CREATE OR REPLACE TYPE SI_PHONE_ACC_T AS TABLE OF SI_PHONE_ACC;
CREATE OR REPLACE TYPE SI_PHONE_ACC AS OBJECT
(
PHONE_ACC VARCHAR2(15);
);
Below is generally passed to the procedure as an input from UI end.
Example:
SI_PHONE_ACCT_T( SI_PHONE_ACC('123-345-6543'),SI_PHONE_ACC('999-999-9999'), SI_PHONE_ACC( 'ax878974545787wp')); -- first 2 are phone no., 3rd is account no.
Phonetable:
Emp_id--- phone_number
1 -- 123-345-6543
2 -- 999-999-9999
3--- 897-897-8781
Account table:
Emp_id--- account_number
10 -- A0000
20 -- B0000
30--- ax878974545787wp
CREATE OR REPLACE PACKAGE BODY order_mgr
IS
PROCEDURE ins_trees ( p_emp_details_in IN SI_PHONE_ACC_T )
BEGIN
-- Now, I need to retrieve emp_ids from Phone and Account tables based on the phone or account numbers passed in the input parameter. please let me know how to do this.
---once I get those emp_id's, i need to insert into employee table which contains only one column emp_id.
--Please let me know how to do this.
FOR i IN 1 .. p_emp_details_in.count
LOOP
INSERT into employee (emp_id)
values(??);
END IF;
END LOOP;
END;
PROCEDURE ins_trees ( p_emp_details_in IN SI_PHONE_ACC_T )
BEGIN
INSERT into employee (emp_id)
select Emp_id
from table(p_emp_details_in) t
, Phone_table t2
where t.PHONE_ACC = t2.phone_number
union
select Emp_id
from table(p_emp_details_in) t
, Account_table t2
where t.PHONE_ACC = t2.account_number
;
END;
/
I've created a after update trigger and would like to add data from two different tables(GORADID and SPRIDEN) when the update fires. The both of the tables are connected by one column(PIDM), so therefore is it possible to also collect data from table 2 ? so far i been getting errors such as ORA: no bind variables..
I also tried doing a select statements. But also no luck. Any suggestions would help.
error: psl-00049: bad bind variable ':new.spriden_id'
error: psl-00049: bad bind variable ':new.spriden_first_name'
error: psl-00049: bad bind variable ':new.spriden_last_name'
Your trigger belongs to GORADID table and :new and :old represent this table
can you try change your trigger like this ?
CREATE OR REPLACE TRIGGER GORADID_UPDT_TRG1
AFTER UPDATE OF GORADID_ADDITIONAL_ID
ON GORADID
FOR EACH ROW
DECLARE
SZRGORA_AUDIT_USER_BANNER_ID VARCHAR2 (150 CHAR);
SZRGORA_AUDIT_STUDENT_BANNER VARCHAR2 (9 CHAR);
SZRGORA_AUDIT_USER_FIRST_NAME VARCHAR2 (150 CHAR);
SZRGORA_AUDIT_USER_LAST_NAME VARCHAR2 (150 CHAR);
SZRGORA_AUDIT_ADDITIONAL_ID VARCHAR2 (50 CHAR);
SPRIDEN_ID VARCHAR2 (9 CHAR);
BEGIN
SELECT USER INTO SZRGORA_AUDIT_USER_BANNER_ID FROM DUAL;
SELECT SPRIDEN_ID
INTO SZRGORA_AUDIT_STUDENT_BANNER
FROM SPRIDEN
WHERE SPRIDEN_PIDM =:old.GORADID_PIDM;
SELECT SPRIDEN_FIRST_NAME, SPRIDEN_LAST_NAME
INTO SZRGORA_AUDIT_USER_FIRST_NAME, SZRGORA_AUDIT_USER_LAST_NAME
FROM SATURN.SPRIDEN
WHERE SPRIDEN_PIDM = (SELECT PIDM
FROM SATURN.IDM_STAFF_AFF_ST
WHERE USERNAME = USER);
INSERT INTO SZRGORA_AUDIT
VALUES (SZRGORA_AUDIT_STUDENT_BANNER,
:new.GORADID_ADDITIONAL_ID,
:old.GORADID_ADDITIONAL_ID,
SZRGORA_AUDIT_USER_FIRST_NAME,
SZRGORA_AUDIT_USER_LAST_NAME,
USER,
'UPDATE',
SYSDATE,
:new.GORADID_SURROGATE_ID,
:new.GORADID_VERSION,
:new.GORADID_VPDI_CODE);
END;
Try below code for your trigger. Please note that you can use :new and :old only for columns of the table GORADID as you are writing trigger ON GORADID table.
You are selecting USER INTO SZRGORA_AUDIT_USER_BANNER_ID. So you should use SZRGORA_AUDIT_USER_BANNER_ID in your next queries instead of saying USER. Directly saying USERNAME = USER will not work I think.
CREATE OR REPLACE TRIGGER AUDIT_USER.GORADID_UPDT_TRG1
AFTER UPDATE OF GORADID_ADDITIONAL_ID
ON GORADID
FOR EACH ROW
DECLARE
v_SZRGORA_AUDIT_USER_BANNER_ID VARCHAR2(150 CHAR);
v_SZRGORA_AUDIT_STUDENT_BANNER VARCHAR2(9 CHAR);
v_SZRGORA_AUDIT_USER_FIRST_NAME VARCHAR2(150 CHAR);
v_SZRGORA_AUDIT_USER_LAST_NAME VARCHAR2(150 CHAR);
BEGIN
SELECT USER INTO v_SZRGORA_AUDIT_USER_BANNER_ID FROM DUAL;
SELECT SPRIDEN_ID
INTO v_SZRGORA_AUDIT_STUDENT_BANNER
FROM SATURN.SPRIDEN
WHERE SPRIDEN_PIDM = :new.GORADID_PIDM
AND GORADID_ADDITIONAL_ID = :new.GORADID_ADDITIONAL_ID;
SELECT SPRIDEN_FIRST_NAME, SPRIDEN_LAST_NAME
INTO v_SZRGORA_AUDIT_USER_FIRST_NAME, v_SZRGORA_AUDIT_USER_LAST_NAME
FROM SATURN.SPRIDEN
WHERE SPRIDEN_PIDM =
(SELECT PIDM FROM SATURN.IDM_STAFF_AFF_ST
WHERE USERNAME = v_SZRGORA_AUDIT_USER_BANNER_ID);
INSERT INTO AUDIT_USER.SZRGORA_AUDIT VALUES
( v_SZRGORA_AUDIT_STUDENT_BANNER,
:new.GORADID_ADDITIONAL_ID,
:old.GORADID_ADDITIONAL_ID,
v_SZRGORA_AUDIT_USER_FIRST_NAME,
v_SZRGORA_AUDIT_USER_LAST_NAME,
v_SZRGORA_AUDIT_USER_BANNER_ID,
'UPDATE',
SYSDATE,
:new.GORADID_SURROGATE_ID,
:new.GORADID_VERSION,
:new.GORADID_VPDI_CODE);
END;
/
I want to update the record if already exists based on where condition or else insert. I have written query with delete and insert I am facing difficulty into converting into update and insert.
PS: I have tried using SQL%ROWCOUNT but I think i missed somewhere in syntax.
Any help would be appreciated.
Below is the proc i am using
Create Or Replace Procedure sal_proc(Empid Varchar2,Fmdt Date,bp Number)
As
Begin
--delete
delete from Emp_Sal
Where Empid = Empid
And Fmdt = Fmdt;
--insert
Insert Into Emp_Sal(empid,fmdt,Basicpay) Values (empid,fmdt,Bp);
End;
You do not need a procedure; you can use MERGE to update or insert a row at the same time:
merge into Emp_Sal e
using (
/* your values to insert/update */
select 2 as Empid, 'c' as Fmdt, 100 as Bp from dual
) x
on ( e.Empid = x.Empid And e.Fmdt = x.Fmdt)
when matched
then /* if a record exists, update */
update set Basicpay = Bp
when not matched
then /* it the record does not exist, insert */
insert values (x.empid, x.fmdt, x.Bp)
Of course you can use this inside a procedure to handle your input parameters or do whatever you may need to do in your procedure:
Create Or Replace Procedure sal_proc(Empid Varchar2,Fmdt Date,bp Number)
As
Begin
merge into Emp_Sal e
using (
/* your values to insert/update */
select Empid as Empid, Fmdt as Fmdt, bp as Bp from dual
) x
on ( e.Empid = x.Empid And e.Fmdt = x.Fmdt)
when matched
then /* if a record exists, update */
update set Basicpay = Bp
when not matched
then /* it the record does not exist, insert */
insert (empid,fmdt,Basicpay) values (x.empid, x.fmdt, x.Bp);
End;
An hint: use parameter names different fron column names to avoid confusion; a good practice could be use parameter names like p_XXX; just an example of how dangerous this can be:
SQL> create or replace procedure checkPar(n in number) is
2 c number;
3 begin
4 select count(1)
5 into c
6 from checkTab
7 where n = n;
8 --
9 dbms_output.put_line(c);
10 end;
11 /
Procedure created.
SQL> select * from checkTab;
N
----------
1
2
3
SQL> exec checkPar(1);
3
PL/SQL procedure successfully completed.
SQL> exec checkPar(999);
3
PL/SQL procedure successfully completed.
Not very efficient way but should work if huge data is not present in tables
CREATE OR REPLACE PROCEDURE sal_proc (E_Empid VARCHAR2, F_Fmdt DATE, b_bp NUMBER)
AS
var number;
BEGIN
Begin
--Checking if record exists
select 1
into var
from Emp_Sal
Where Empid = E_Empid
And Fmdt = F_Fmdt;
exception
when no_data_found then
var:= 0;
End;
if var <> 1 then
--insert
INSERT INTO Emp_Sal (empid, fmdt, Basicpay)
VALUES (e_empid, f_fmdt, b_Bp);
else
update Emp_Sal
set col ....<>;
end if;
END;
Say I have 2 objects MY_OBJ, MY_NESTED_TABLE_OBJ
CREATE OR REPLACE TYPE MY_NESTED_TABLE_OBJ IS TABLE OF VARCHAR2(100);
CREATE OR REPLACE TYPE MY_OBJ AS OBJECT (
simple_atribute NUMBER(6),
table_attribute MY_NESTED_TABLE_OBJ,
MEMBER PROCEDURE doStuff(text VARCHAR2)
) NOT FINAL INSTANTIABLE;
MY_OBJ's table
CREATE TABLE TBL_MY_OBJ OF MY_OBJ
( CONSTRAINT PK_simple_atribute PRIMARY KEY(simple_atribute))
NESTED TABLE table_attribute STORE AS attribute_nst;
How do I insert a VARCHAR2(100) into the nested table belonging to table_attribute?? What is the sintax??
Doing a simple insert like: INSERT INTO attribute_nst VALUES ('some text'); gives the error
cannot reference nested table column's storage table
What i want is to do insert from within PROCEDURE doStuff(text VARCHAR2), i've tried:
INSERT INTO SELF.attribute_nst VALUES (text);
INSERT INTO attribute_nst VALUES (text);
INSERT INTO table_attribute VALUES (text);
...and other combination and no nothing, so please help!
SQL> CREATE OR REPLACE TYPE BODY MY_OBJ AS
2 member procedure doStuff(text varchar2) is
3 begin
4 table_attribute.extend(1);
5 table_attribute(table_attribute.count) := text;
6 end;
7 end;
8 /
Type body created.
SQL> declare
2 l_my_obj My_Obj := My_Obj(1,MY_NESTED_TABLE_OBJ());
3 begin
4 l_my_obj.doStuff('abc');
5 l_my_obj.doStuff('def');
6
7 insert into tbl_my_obj values (l_my_obj);
8 end;
9 /
PL/SQL procedure successfully completed.
SQL> select * from tbl_my_obj;
SIMPLE_ATRIBUTE
---------------
TABLE_ATTRIBUTE
------------------------------------------------------------
1
MY_NESTED_TABLE_OBJ('abc', 'def')
Try this
insert into tbl_my_obj values (1, new my_nested_table_obj(text1, text2));
I am trying to use autoincrement on my package without using trigger.. Can someone explain me how I have to use it in my package.. I did this way didnt work its complaining abt variable not being declared or type not assigned.. I saw other autoincrement questions but nobody has used auto increment without trigger on package
PROCEDURE insertExample (
user_id_in IN sample.seq_user_id.nextval,
name_in IN sample.name%TYPE,
age_in IN sample.age%TYPE )
IS
BEGIN
INSERT INTO sample
(seq_user_id.nextval, name, age)
VALUES
(user_id_in, name_in, age_in);
END insertExample;
Are you wanting to allow a custom user_id to be passed in or always use the sequence?
In the first case, you would need something like:
CREATE OR REPLACE PROCEDURE insertexample (
user_id_in in sample.user_id%type,
name_in in sample.name%type,
age_in in sample.age%type
)
IS
BEGIN
insert into sample
(user_id, name, age
)
values (nvl(user_id_in, seq_user_id.nextval), name_in, age_in);
END insertexample;
If you always want to use the sequence (which is probably the right choice), just take out that input parameter and the NVL:
CREATE OR REPLACE PROCEDURE insertexample (
name_in in sample.name%type,
age_in in sample.age%type
)
IS
BEGIN
insert into sample
(user_id, name, age
)
values (seq_user_id.nextval, name_in, age_in);
END insertexample;
You want something like
PROCEDURE insertExample (
name_in IN sample.name%TYPE,
age_in IN sample.age%TYPE )
IS
BEGIN
INSERT INTO sample
(user_id, name, age)
VALUES
(seq_user_id.nextval, name_in, age_in);
END insertExample;
Your not that far away from a working solution:
PROCEDURE insertExample (
name_in IN sample.name%TYPE,
age_in IN sample.age%TYPE )
IS
BEGIN
INSERT INTO sample (user_id, name, age)
VALUES (seq_user_id.nextval, name_in, age_in);
END insertExample;
I'm assuming that the table has at least three columns called user_id, name and age. Furthermore, I'm assuming that you have already created a sequence called seq_user_id (CREATE SEQUENCE seq_user_id START WITH 1 INCREMENT BY 1).
As the user Id is not automatically assigned, it is no longer part of the parameter list.
I would phrase your procedure as a FUNCTION instead, and return the new ID to the caller:
FUNCTION insert_user
(
name_in IN users.name%TYPE,
age_in IN users.age%TYPE
)
RETURN users.id%TYPE
IS
v_id users.id%TYPE;
BEGIN
INSERT INTO users (
user_id,
name,
age
) VALUES (
seq_user_id.nextval,
name_in,
age_in
)
RETURNING
user_id
INTO
v_id
;
RETURN v_id;
END insert_user;
This is generally a more useful pattern for inserts, especially where you may want to subsequently insert child records in other tables.