SQL Query alter table auto increment in SQL Plus Oracle 10g - oracle

I have this SQL Query and I am trying to modify my column so it has an auto increment Property, But when I execute the query I either have a problem code ORA-00933 SQL command not properly ended
This is what I have tried
ALTER TABLE BF_USER DROP COLUMN USER_ID
ALTER TABLE BF_USER ADD USER_ID INT IDENTITY(1,1);

SQL*Plus is Oracle's command-line tool. In that case:
SQL> create table bf_user (user_id number, name varchar2(10));
Table created.
SQL> alter table bf_user drop column user_id;
Table altered.
SQL> alter table bf_user add user_id number generated always as identity;
Table altered.
Testing:
SQL> insert into bf_user(name) values ('Littlefoot');
1 row created.
SQL> select * from bf_user;
NAME USER_ID
---------- ----------
Littlefoot 1
SQL>
As you use Oracle 10g (which doesn't support identity columns), use combination of a sequence and a database trigger:
SQL> create table bf_user (user_id number, name varchar2(10));
Table created.
SQL> create sequence bf_seq;
Sequence created.
SQL> create or replace trigger trg_bi_bfu
2 before insert on bf_user
3 for each row
4 begin
5 select bf_seq.nextval into :new.user_id from dual;
6 end;
7 /
Trigger created.
SQL> insert into bf_user (name) values ('Nayeon');
1 row created.
SQL> select * from bf_user;
USER_ID NAME
---------- ----------
1 Nayeon
SQL>

Related

Alter table clg ADD CONSTRAINT UC_Person NOT NULL(AGE); why do I get an error?

This throws an error:
ALTER TABLE TABLE_NAME
ADD CONSTRAINT UC_Person NOT NULL(AGE);
This works fine:
ALTER TABLE TABLE_NAME
MODIFY Column_name data_type not null;
Question is that 1st one why getting the error and for unique will not get an error.
Why? Because you can't just make up syntax the way you'd want it to be - it is here so that you'd follow it.
If you want to name the NOT NULL constraint, then do it as follows:
SQL> create table table_name (age number);
Table created.
SQL> alter table table_name modify age constraint uc_person not null;
Table altered.
SQL>
It gets simpler if you don't care about constraint name:
SQL> drop table table_name;
Table dropped.
SQL> create table table_name (age number);
Table created.
SQL> alter table table_name modify age not null;
Table altered.
SQL>

Can adding FK or PK constraints invalidate something?

I have a couple of tables with primary-foreign key relations but those constraints do not actually exist. Now I want to add them with an alter table statement.
Will those commands cause any object that depends on the tables to become invalid?
Thanks.
This is a good question. Let's poke the database and see. Here's the set up:
SQL> create table p23 (id number not null, col1 varchar2(10));
Table created.
SQL> create table c23 (id number not null, p_id number not null, col1 varchar2(10));
Table created.
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 values (1, 'ABC');
5 insert into c23 values (11, 1, 'DEF');
6 end;
7 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
Everything is copacetic. Now we'll add some constraints.
SQL> alter table p23 add constraint p23_pk primary key (id);
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table c23 add constraint c23_p23_fk
2 foreign key (p_id) references p23;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
All is still cool. But when we change a table's structure this happens...
SQL> alter table p23 add col2 date;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
INVALID
SQL>
... which is exactly what we would want.
Note that I ran these tests on 11gR2. Oracle introduced fine-grained dependency tracking in 11g, which made programmatic objects more robust when we run DDL on their dependencies. Find out more. So the outcome might be different in earlier versions. It pays to test.
" what is the reason for the procedure to become invalid?"
Structural changes such as adding, modifying or dropping a column potentially have an impact on referencing objects. The procedure had insert statements which didn't specify target columns. So adding a column introduced an ORA-00947: not enough values bug.
But suppose we employed good practice and specified columns?
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 (id, col1) values (1, 'ABC');
5 end;
6 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table p23 add col4 number;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
Now we're protected by fine-grained dependency tracking. Well, sort of. We shouldn't substitute dependency tracking for impact analysis:
SQL> alter table p23 add col5 date not null;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
The procedure has a VALID state but it will still fail when we run it, because it doesn't populate the new mandatory column.

INSERT ALL statement in Oracle failing to insert

I have multiple rows to insert in a table.
There are some constraints in the table which fails for few of the rows.
But with INSERT ALL statement, when it finds the first insert with constraint fails, it stops inserting to oracle db and rest of the data which are proper is also not inserted.
Will it be working this way only. Or do we have any method in which insert all valid data and ignore the other inserts in the INSERT ALL.
when it finds the first insert with constraint fails, it stops inserting to oracle db and rest of the data which are proper is also not inserted. Will it be working this way only.
Yes, it is designed to work that way. INSERT ALL statement will fail to insert if any one row errors out.
For example,
SQL> CREATE TABLE t(a NUMBER);
Table created.
SQL> ALTER TABLE t ADD CONSTRAINT t_unique UNIQUE(a);
Table altered.
SQL> INSERT INTO t(a) VALUES(1);
1 row created.
SQL> INSERT ALL
2 INTO t (a) VALUES (1)
3 INTO t (a) VALUES (2)
4 INTO t (a) VALUES (3)
5 SELECT * FROM dual;
INSERT ALL
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.T_UNIQUE) violated
SQL> SELECT * FROM t;
A
----------
1
If you want other values to be inserted which are correct, then put them as individual insert statements and execute all the insert statements as a script.
For example,
SQL> CREATE TABLE t(a NUMBER);
Table created.
SQL> ALTER TABLE t ADD CONSTRAINT t_unique UNIQUE(a);
Table altered.
SQL> INSERT INTO t(A) VALUES(1);
1 row created.
SQL> INSERT INTO t(a) VALUES(1);
INSERT INTO t(a) VALUES(1)
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.T_UNIQUE) violated
SQL> INSERT INTO t(A) VALUES(2);
1 row created.
SQL> INSERT INTO t(A) VALUES(3);
1 row created.
SQL> SELECT * FROM t;
A
----------
1
2
3

Count of table before and after insert inside a trigger

Is it possible to check the count of a table before any changes happen and the count after the insert and match them inside the same trigger?
for ex: old.count and new.count (before and after insert) ?
old.count and new.count (before and after insert)
Nothing stops you from using SELECT COUNT(*) in a before insert trigger. Of course, you won't do it in a after insert trigger, since a select count(*) on the same table on which an after trigger is defined would throw mutating table error. One way is autonomous transaction. But, in your case, it isn't that complex.
You could define a BEFORE INSERT TRIGGER and take the table count. The after insert count could be taken manually after the actual insert is done.
For example, I have a table t1 with one row. I have defined a before insert trigger on it, which would give me the table count before the insert happens.
SQL> DROP TABLE t1 PURGE;
Table dropped.
SQL>
SQL> CREATE TABLE t1 (A NUMBER);
Table created.
SQL>
SQL> INSERT INTO t1 VALUES (1);
1 row created.
SQL>
SQL> SELECT * FROM t1;
A
----------
1
SQL>
SQL> CREATE OR REPLACE TRIGGER trg
2 BEFORE INSERT
3 ON t1
4 FOR EACH ROW
5
6 DECLARE
7 val number;
8 BEGIN
9 SELECT COUNT(*)
10 INTO val
11 FROM t1;
12
13 DBMS_OUTPUT.PUT_LINE('TABLE COUNT BEFORE INSERT = '||val);
14
15 END;
16 /
Trigger created.
SQL>
SQL> set serveroutput on
SQL> INSERT INTO t1 VALUES (1);
TABLE COUNT BEFORE INSERT = 1
1 row created.
SQL>
SQL> SELECT COUNT(*) FROM t1;
COUNT(*)
----------
2
SQL>
So, you see TABLE COUNT BEFORE INSERT = 1 and then after insert the count is 2.

Does altering or drop-recreating a table in oracle affects the policies defined on it

If i have a table and a defined policy on it then do I need to redefine the policy if I drop and recreate the table or alter it, provided that the alteration or the recreation of the table does not alter elements that the function needs to see?
"do I need to redefine the policy if I
drop and recreate the table"
Yes. Let's create a policy.
SQL> exec dbms_rls.add_policy('APC', 'T23', 'DEPTPOL', 'APC', 'security_policies.get_deptno_predicate')
PL/SQL procedure successfully completed.
SQL> select count(*) from user_policies;
COUNT(*)
----------
1
SQL> exec security_policies.set_deptno(20)
PL/SQL procedure successfully completed.
SQL> select count(*) from t23;
COUNT(*)
----------
6
SQL>
so that works. But if we drop and re-create the table (using a backup I prepared earlier) ...
SQL> drop table t23
2 /
Table dropped.
SQL> create table t23 as select * from t23a
2 /
Table created.
SQL> select count(*) from t23;
COUNT(*)
----------
11
SQL> exec security_policies.set_deptno(20)
PL/SQL procedure successfully completed.
SQL> select count(*) from t23;
COUNT(*)
----------
11
SQL> SQL> select count(*) from user_policies;
COUNT(*)
----------
0
SQL>
"So the question is if I must redefine
the policy even if I will not change
anything in the definition."
No. Providing the change doesn't invalidate the generated predicate altering a table doesn't drop the policy:
SQL> exec dbms_rls.add_policy('APC', 'T23', 'DEPTPOL', 'APC', 'security_policies.get_deptno_predicate')
PL/SQL procedure successfully completed.
SQL> alter table t23 modify deptno number(3,0)
2
SQL> desc t23
Name Null? Type
----------------------------------------- -------- ----------------------------
NAME VARCHAR2(12 CHAR)
ID NUMBER
AGE NUMBER(4)
DEPTNO NUMBER(2)
SQL> alter table t23 modify deptno number(3,0)
2 /
Table altered.
SQL> exec security_policies.set_deptno(20)
PL/SQL procedure successfully completed.
SQL> select count(*) from t23;
COUNT(*)
----------
6
SQL>
Note that the change modified the column which is tested by the predicate and the policy still remains in force.
"does a 'CREATE OR REPLACE VIEW'
statement drops and recreates it or
does it alter it?"
Let's try it:
SQL> create view v23 as select * from t23;
View created.
SQL> exec dbms_rls.add_policy('APC', 'V23', 'DEPTPOLV', 'APC', 'security_policies.get_deptno_predicate')
PL/SQL procedure successfully completed.
SQL> exec security_policies.set_deptno(10)
PL/SQL procedure successfully completed.
SQL> select count(*) from v23;
COUNT(*)
----------
5
SQL> create or replace view v23 as select name, age from t23;
View created.
SQL> select count(*) from v23;
select count(*) from v23
*
ERROR at line 1:
ORA-28113: policy predicate has error
SQL>
Okay, so that's an error because the view's new projection doesn't include the column in the predicate. But it suggests teh ploicy is still in place. So let's fix that error:
SQL> create or replace view v23 as select name, age, deptno from t23;
View created.
SQL> select count(*) from v23;
COUNT(*)
----------
5
SQL>

Resources