How to find sequnce name which associated to table with table name - oracle

How to find sequnce name which is associated to mytable in Oracle sql
Select * user_sequwnces where table_name =tablename

If you created a table using the IDENTITY clause, then the sequence name will aligned with the object ID of the table, eg
SQL> create table t ( x int generated as identity);
Table created.
SQL> select object_id from user_objects
2 where object_name = 'T';
OBJECT_ID
----------
4282429
SQL> select sequence_name
2 from user_sequences
3 where sequence_name like '%4282429%';
SEQUENCE_NAME
-----------------------------------------------------
ISEQ$$_4282429
But if you just use a sequence of your own as a default, there is no such relationship, eg
SQL> create sequence blah;
Sequence created.
SQL> create table t1 ( x int default blah.nextval, y int );
Table created.
SQL> create table t2 ( x int default blah.nextval, y int );
Table created.
SQL> create table t3 ( x int default blah.nextval, y int );
Table created.
You can even drop the sequence ... and that only would become an issue later when you try to use it, eg
SQL> drop sequence blah;
Sequence dropped.
SQL> insert into t1 (x,y) values (0,0);
1 row created.
SQL> insert into t1 (y) values (0);
insert into t1 (y) values (0)
*
ERROR at line 1:
ORA-02289: sequence does not exist

Related

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

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>

Oracle SQL procedure getting invalid after table alter

When trying to alter a table , one of the procedure which has only select statement is getting invalid.
table scripts:
create table t1(a number,b number);
create or replace procedure p1
is
x number;
y number;
begin
select a,b into x,y from t1;
end;
/
create or replace procedure p2(i number)
is
x number;
y number;
begin
select a,b into x,y from t1 where i=1;
end;
/
alter table t1 add (d number);
select object_name,status from dba_objects where object_name in ('T','P1','P2');
T VALID
P1 VALID
P2 INVALID
observed that when procedure takes in parameter and if we are using it in the select statement, the object is getting invalid or else it is not getting invalid.
Is it possible to alter the table without the procedure getting invalid?
Actually, your object is not really invalid. The issue happens as your second procedure contains a where clause that produces an invalidation in the dictionary based on rules.
If you run the procedure, it will become valid automatically.
Demo
Oracle 19c
SQL> alter session set current_schema=test1 ;
Session altered.
SQL> create table t1(a number,b number);
Table created.
SQL> create or replace procedure p1
is
x number;
y number;
begin
select a,b into x,y from t1;
end;
/ 2 3 4 5 6 7 8
Procedure created.
SQL> create or replace procedure p2(i number)
is
x number;
y number;
begin
select a,b into x,y from t1 where i=1;
end;
/
2 3 4 5 6 7 8
Procedure created.
SQL> alter table t1 add (d number);
Table altered.
SQL> select object_name,status from dba_objects where object_name in ('T1','P1','P2') and owner='TEST1' ;
OBJECT_NAME STATUS
------------------------- --------------------
P1 VALID
P2 INVALID
T1 VALID
Now, if the procedure was really invalid, you could not execute it. Let's insert one row in your table and try to run it.
SQL> insert into t1 values ( 1 ,1 ,1) ;
1 row created.
SQL> commit ;
Commit complete.
SQL> set serveroutput on
SQL> exec p2 ( i=>1 ) ;
PL/SQL procedure successfully completed.
SQL> select object_name,status from dba_objects where object_name in ('T','P1','P2') and owner='TEST1' ;
OBJECT_NAME STATUS
------------------------- --------------------
P1 VALID
P2 VALID
T1 VALID
There are internal rules which define the invalidation of objects in the dictionary, such as procedures, functions or packages when some changes happen in the objects which those have dependencies upon.
In this specific case, there is no real invalidation, as the object was only marked as invalid in the dictionary after the DDL was executed.
The reason why the first one was not invalid is because it does not contain any where clause, and only is retrieving the two existing columns. The second becomes invalid as it contains a where clause to a PLSQL variable. See below
https://docs.oracle.com/cd/E24693_01/appdev.11203/e17125/adfns_dependencies.htm#CHDJIIFC

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.

How to auto increment the id in oracle?

Is there any way to auto increment the id in oracle?
UPDATE: It's working but the sequence start in 2 instead of 1. I already set the sequence start with 1
If it possible not use the sequence but still id's will be auto increment?
Here:
CREATE TABLE tblname
(
fieldname_id number(25),
contract_number number(12) not null,
CONSTRAINT letter_status_pk PRIMARY KEY (fieldname_id, contract_number)
);
Sequence w/trigger:
create sequence fieldname_id_sequence start with 1
increment by 1
minvalue 1;
create trigger tr_tblname
before insert on tblname
for each row
begin
select fieldname_id_sequence.nextval into :NEW.fieldname_id from dual;
end;
insert data:
insert all
into tblname(contract_number,fieldname1,fieldname2,fieldname3,fieldname4,fieldname5,fieldname6,fieldname7,fieldname8,fieldname8,fieldname10,fieldname11) values(3300026224,'values','values','values','3/12/2014','values','values','3/18/2014','3/7/2014','values','values')
into tblname(contract_number,fieldname1,fieldname2,fieldname3,fieldname4,fieldname5,fieldname6,fieldname7,fieldname8,fieldname8,fieldname10,fieldname11) values (3300016335,'values','values','values','3/12/2014','values','values','3/18/2014','3/7/2014','values','values')
select 1 from dual;
you can model it easily with a sequence and a trigger:
Create sequence sequence_name start with value increment by value minvalue value maxvalue value;
First, let’s create an emp table with primary key constraint on emp_id column.
SQL> create table emp ( emp_id number(10),
fname varchar2(25),
lname varchar2(25),
constraint pk_emp_id PRIMARY KEY(emp_id)
);
Now let’s create a sequence.
SQL> Create sequence emp_sequence start with 1
increment by 1
minvalue 1
maxvalue 10000;
Now we have created a sequence object named emp_sequence with starting value as 1 and incrementing by 1 from 1 (minvalue) to 10000 (maxvalue)
SQL> insert into emp (emp_id,fname,lname) values(emp_sequence.nextval,'Darvin','Johnson'); SQL>
insert into emp (emp_id,fname,lname) values(emp_sequence.nextval,'Mig','Andrews');
SQL> insert into emp (emp_id,fname,lname) values(emp_sequence.nextval,'Alex','Martin');
SQL> insert into emp (emp_id,fname,lname) values(emp_sequence.nextval,'Jon','paul');
SQL> insert into emp (emp_id,fname,lname) values(emp_sequence.nextval,'Yatin','Bones');
In emp_sequence.nextval where emp_sequence is the name of sequence we created above and nextval is a function that is used to assign the next number from emp_sequence to emp_id column in emp table.
Oracle 12c introduces IDENTITY COLUMNS.
SQL> CREATE TABLE new_identity_table
2 (
3 ID NUMBER GENERATED ALWAYS AS IDENTITY,
4 text VARCHAR2(50)
5 );
Table created.
SQL>
SQL> INSERT
2 INTO new_identity_table
3 (
4 text
5 )
6 VALUES
7 (
8 'This table has an identity column'
9 );
1 row created.
SQL> column text format A40;
SQL>
SQL> select * from new_identity_table;
ID TEXT
---------- ----------------------------------------
1 This table has an identity column
SQL>
Oracle creates a sequence to populate the identity column. You can find it named as ISEQ$$
SQL> select sequence_name, min_value, max_value, increment_by from user_sequences;
SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY
-------------------- ---------- ---------------------------- ------------
ISEQ$$_93199 1 9999999999999999999999999999 1
SQL>
More more information about the identity columns, use the ALL_TAB_IDENTITY_COLS view.
SQL> SELECT table_name,
2 column_name,
3 generation_type,
4 identity_options
5 FROM all_tab_identity_cols
6 WHERE owner = 'LALIT'
7 ORDER BY 1, 2;
TABLE_NAME COLUMN_NAME GENERATION IDENTITY_OPTIONS
-------------------- --------------- ---------- --------------------------------------------------
NEW_IDENTITY_TABLE ID ALWAYS START WITH: 1, INCREMENT BY: 1, MAX_VALUE: 9999999
999999999999999999999, MIN_VALUE: 1, CYCLE_FLAG: N
, CACHE_SIZE: 20, ORDER_FLAG: N
SQL>

Oracle dropping and recreating synonyms

When we use CTAS like this:
create table big2 as select * from big1;
drop table big1;
rename big2 to big1;
If there are synonym existing on big1, do we need to drop synonym on big1 prior to delete and recreate them? Or is this not necessary?
No. Becuase Synonym is just another name you give to an object ( either within your schema or not). See this code below.
(BTW, shouldn't you rename table t2 to t1 directly?? Does your CTAS have other where conditions, which you are not showing here?)
SQL> create table t1 as
2 select * from scott.emp;
Table created.
SQL> select count(*) from t1;
COUNT(*)
----------
14
SQL> select count(*) from t2;
select count(*) from t2
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create synonym s1 for t1;
Synonym created.
SQL> create table t2 as
2 select * from t1;
Table created.
SQL> drop table t1;
Table dropped.
SQL> alter table t2 rename to t1;
Table altered.
SQL> select count(*) from t1;
COUNT(*)
----------
14
SQL> select count(*) from s1;
COUNT(*)
----------
14

Resources