two tables with the same sequence - oracle

Is possible to have two tables with the same incrementing sequence?
I was trying to do a tree with ID, NAME, ParentID and i have to join two tables.
If i have different id the tree scheme of ID - ParentId will not work.
Table A Table B
ID | NAME | PID ID | NAME | PID
1 | xpto | 0 1 | xpto | 1

If you are doing both inserts at the same time, you can use SEQUENCE.NEXTVAL for the insert into the first table to get a new ID, and then SEQUENCE.CURRVAL for the insert into the second table to reuse the same ID.

I found the answer: "Sequence numbers are generated independently of tables, so the same sequence can be used for one or for multiple tables."
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_6015.htm
Tanks for your help.

You could have a master table that is nothing but the sequence PK/FK and then have two child tables. Insert a row in the master just to get the sequence and then use that sequence as the PK in the child tables. If the child tables have the same sequence then why is not one table?

create sequence v_seq
INCREMENT by 1
minvalue 1
maxvalue 10;
Sample Image
create table v_t_s_emp(v_id number,vname varchar2(10));
insert into v_t_s_emp values(v_seq.nextval,'krishna');
create table v_t_s_emp1(v_id number,vname varchar2(10));
insert into v_t_s_emp1 values(v_seq.nextval,'RAMesh');
commit;
select * from v_t_s_emp
union all
select * from v_t_s_emp1;

Related

SQL Foreign key to two different tables

I have a problem like
Table A:
-- TableBCId
Table B:
-- Id
Table C:
-- Id
I am looking for a way to create a foreign key table A where an entry can be either in table B or table C
Example entries:
Table A:
-- TableBCId: 1
-- TableBCId: 2
Table B:
-- Id: 1
Table C:
-- Id: 2
I want to avoid if possible:
- Two columns in table A
- Default values
- Additional tables
- Creation of an base entity is not possible
Every idea welcome
The normal way to implement this requirement is with 2 columns, 2 foreign key constraints, and a check constraint to ensure exactly of of the columns populated (if this is a requirement):
create table a
( ...
, b_id references b
, c_id references c
, constraint <name> check ( (b_id is null and c_id is not null)
or (b_id is not null and c_id is null)
)
);
You could, if it helps your UI, create a view over that table that combines B_ID and C_ID into a single column.
But you have said you don't want 2 columns, why is that?
The reason why this is hard is because the data model is wrong. A foreign key references only one table. A table can have more than one foreign key but each is separate. Apart from anything else, how would you know whether bc_id referenced b.id or c.id?
One explanation for this scenario is that table A should really be two tables, BA referencing B and CA referencing C. Alternatively A should reference a super-type table, of which B and C are sub-types. Without knowing the actual business domain it's hard to be sure.
Anyway, the path of least change is two columns.
You can use a insert/update trigger on your Table_A.
Maybe something like this:
CREATE TRIGGER Table_a_trgr
BEFORE INSERT OR UPDATE
on Table_a
FOR EACH ROW
DECLARE
c_row NUMBER;
BEGIN
SELECT count(*)
INTO c_row
FROM (
SELECT ID FROM table_b WHERE id = :NEW.TableBCId
UNION ALL
SELECT ID FROM table_c WHERE İd = :NEW.TableBCId
)
;
IF c_row < 2 THEN
raise_application_error(-20000, 'Error, Foreign Key');
END IF;
END;
/
If you don't want to make a new column in table A.
Then you can make a parent table to B and C.
tableBC:
id
And then create a 1-1 relation with tables B and C to table BC.
tableB:
id,
parent -- 1-1 foreign key to tableBC
tableC:
id,
parent -- 1-1 foreign key to tableBC
Now, in table A
tableA:
id,
TableBCId -- foreign key to tableBC
We have solved a similar problem using this approach.

Using "contains" as a way to join tables?

The Primary key in table one is used as in table 2 but it is modified as so:
Primary key Column in table 1: 123abc
Column in table 2: 123abc_1
I.e. the key is used but then _1 is added to create a unique value in the column of Table 2.
Is there any way that I can join the two tables, the data in the 2 columns is not identical but it very similar. Could I do something like:
SELECT *
FROM TABLE1 INNER JOIN
TABLE2
ON TABLE1.COUMN1 contains TABLE2.COLUMN2;
I.e. checking that the value in Table 1 is within the value in Table 2?
You can check only the first part of column2; for example
SELECT *
FROM TABLE1 INNER JOIN TABLE2
ON INSTR(COLUMN2, COLUMN1) = 1
or
ON COLUMN2 LIKE COLUMN1 || '%'
However, keeping foreign key in such a way can be really dangerous, not to think about performance on large DBs.
You'd better use a different column in Table2 to store the key of Table 1, even adding a constraint.

How to find unique values from set of rows using pentaho kettle?

I have one de normalized table. I want to select all the values from one specific column of that table and load only unique values from that column into separate table.
How to do this using Pentaho Spoon? Please note that I am totally newbie to Spoon. I have tried only hello world transformation in my life.
I have table named 'Employees' which has lots of columns as follows (I have not given unrelated columns here):
+-------------------------------------------------------+
Employees
+-------------------------------------------------------+
employee_number | employee_name | deputed_branch | phone
+-------------------------------------------------------+
Now I want to move only unique branch names into new table named branches using Spoon.
'branches' table will look like following :
+-------------------------------------------------------+
branches
+-------------------------------------------------------+
| branch_id | branch_name
+-------------------------------------------------------+
where branch_id will be unique and auto incremented.
To connect Employees and branches table I will use Employee_branch table which will consist of employee_number and branch_id column.
Can anyone please tell how to do this?
Thanks in advance !!
can't you just do that in the sql?
select distinct deputed_branch from employees
If not; Then use either the unique rows step ( not that it has to be sorted data ) or the group by step. ( also sorted )
or; Memory group by if number of rows is low ( data doesnt need to be sorted )

Oracle database table insertion

I have two tables:
create table Number( num number(5));
create table Entry(id number(3), name varchar(50));
How can I increment the num field of Number table in Oracle whenever I insert something in the Entry table?
You should use a SEQUENCE instead. The "Number" table is an inherently bad idea, because when two sessions are inserting rows concurrently, each session only sees the uncommited value in the Number table.
This is what you should do instead:
create sequence entrySeq;
create table Entry(id number(3), name varchar(50));
create trigger tr_entry before insert on Entry for each row
begin
select entrySeq.nextval into :new.number from dual;
end;
/
Do you want number.num to continually represent the number of rows iin the Entry table? If so you could just define it as a view:
create view number_view
as
select count(*) from Entry
create sequence entrySeq;
create table Entry(id number(3), name varchar(50));
insert into Entry value (entrySeq.nextval, 'MyName');
(You don't need a trigger).
A sequence returns a unique and increasing number value but Oracle doesn't guarantuee that it is gapless. When sometimes transactions are rollbacked the values of column id will contain gaps.

Oracle Sql Update with values using foreign key?

Table 1:
Name, x1-X2, fk1, fk2.
Table 2:
K1(parent for table 1),X
How to update table 1 whose second column x1-x2 depands on fk1,fk2 from Table 2
Table1:
a,1.0,1,2
b,-3.0,2,3
Table 2
1,4.0
2,5.0
3,2.0
With this setup:
CREATE TABLE table2 (k NUMBER PRIMARY KEY, x NUMBER);
CREATE TABLE table1 (
NAME VARCHAR2(10) PRIMARY KEY,
diff NUMBER,
fk1 NUMBER REFERENCES table2,
fk2 NUMBER REFERENCES table2);
the following update will "refresh" the colum table1.diff with the values of table2:
SQL> UPDATE (SELECT child.diff old_diff, parent2.x - parent1.x new_diff
2 FROM table1 child
3 JOIN table2 parent1 ON (child.fk1 = parent1.k)
4 JOIN table2 parent2 ON (child.fk2 = parent2.k))
5 SET old_diff = new_diff
6 WHERE old_diff != new_diff
7 OR (old_diff IS NULL AND new_diff IS NOT NULL)
8 OR (old_diff IS NOT NULL AND new_diff IS NULL);
Only the rows that need updating will be refreshed (thanks to the where clause).
Not quite sure I understand the question, referential integrity constraints do not prevent you from updating a table. If you need to do a lot of work in a transaction you can look into Deferred Constraints. Is there any chance you could clarify what you mean?
Not sure exactly what the problem is, maybe you need to rephrase the question a little.
In general, the foreign key constraint makes sure that there exists a corresponding row in the referenced table.
When you update a row with a foreign key, and try to set a value that does not point to such a master row, you will get an error, either immediately or when you commit (depending on when the constraint is enforced, it can be deferred).
Other than that, the update is no different than any other update.
Since the data in table 1 is dependent on the data in table 2 you won't be able to "Update" table 1 directly.
You will have to perform the update on table 2 and then recalculate table 1.
You could do it inside a transaction or perhaps a trigger on table 2.
Another option may be to have table one only hold the foreign keys and the name and then create a view that calculates the X1-X2 value.
EDIT
After looking at the sample data, I don't think you can unambiguously have table 2 be updates as a result of an update on table 1.
For example if you update the second column of table 1 to be 43, how would you know what values to set the specific rows of table 2 (it could be 40 and 3, 20 and 23, etc.)

Resources