I need solution for data transfer between two tables in Oracle database. Source is relational type and target is object type of table. Here is example:
Source table (existing data):
CREATE TABLE "HISTORY" (
"ID" NUMBER,
"ID_PROCESS" NUMBER,
"ID_UNIT" NUMBER,
"PASS_DATE" DATE DEFAULT SYSDATE
);
CREATE UNIQUE INDEX "HISTORY_PK" ON "HISTORY" ("ID");
ALTER TABLE "HISTORY" ADD CONSTRAINT "HISTORY_PROCESS_FK1"
FOREIGN KEY ("ID_PROCESS") REFERENCES "PROCESS" ("ID");
ALTER TABLE "HISTORY" ADD CONSTRAINT "HISTORY_PROCESS_FK2"
FOREIGN KEY ("ID_UNIT") REFERENCES "UNITS" ("ID");
Target table (empty):
CREATE OR REPLACE TYPE t_history AS OBJECT (
"ID" NUMBER,
"ID_PROCESS" REF t_process,
"ID_UNIT" REF t_unit,
"PASS_DATE" DATE
);
CREATE TABLE o_history OF t_history (
"ID" PRIMARY KEY);
Assuming you've already created types and object tables for the process and unit values, you can do:
INSERT INTO o_history
SELECT t_history(h.id, REF(p), REF(u), h.pass_date)
FROM history h
JOIN o_process p ON p.id_process = h.id_process
JOIN o_unit u ON u.id_unit = h.id_unit;
This gets the ID and pass date from the history table, and gets the references from the other tables for the matching values.
SQL Fiddle demo.
Related
I have three tables. Two basic tables listing objects and a third table logging changes in database. Here is an example.
create table individual (ind_id integer, age integer, name varchar);
create table organisation (org_id integer, city varchar, name varchar);
create TABLE log_table (log_id integer, object_id integer, table_name varchar, information json, log_date date);
I want to ensure that any row in the log_table corresponds to an existing object in either the individual table or the organisation table. This means that the insertion
insert into log_table (object_id,table_name,information,log_date) values (13,'organisation','{"some":"interesting","information":"on the changes"}','2017-11-09');
is valid only if the table organisation contains a record with the ID 13.
How can I do that in PostgreSQL ? If this is not possible, then I suppose I will have to create one column for the individual table and one for the organisation table in the log_table.
You need an entity table:
create table entity (
entity_id serial primary key,
entity_type text check (entity_type in ('individual','organization'))
)
create table individual (
ind_id integer primary key references entity (entity_id),
age integer, name varchar
);
create table organisation (
org_id integer primary key references entity (entity_id),
city varchar, name varchar
);
create TABLE log_table (
log_id integer primary key,
entity_id integer references entity (entity_id),
information json, log_date date
);
You could also use triggers to solve this problem . Seperate triggers can be made on individual and organisation table which could be on before update ,after update , after insert actions .
You could add one column in log table which would correspond to action performed in base table i.e update or insert .
Also you could add unique constraint on table name and object id .
This would eventually lead to logging every possible operation in table without changing in application code .
Hope this helps !
Starting from your current design you can enforce what you want declaratively by adding to each entity table a constant checked or computed/virtual table/type variant/tag column and a FK (foreign key) (id, table) to the log table.
You have two kinds/types of logged entities. Google sql/database subtypes/polymorphism/inheritance. Or (anti-pattern) 2/many/multiple FKs to 2/many/multiple tables.
I have a situation where I would I have a many-to-many relationship on a single table. This is just a quick example of one example. Right now it is just a raw csv dump into a table. But I would like to add a cross reference table or a constraint so that when I can query a vendor. For brevity, I just show the two ID's.
How would I go about adding that relationship to the below example? I am using SQLlite at the moment but I plan on translating it to either MS server or Postgres for the final tables.
global_duns vendor_duns
9581091 53506312
9581091 961273620
79735371 53506312
79735371 79735371
79735371 135962137
Here is what I've tried so far:
DROP TABLE IF EXISTS company;
PRAGMA foreign_keys=off;
CREATE TABLE company
(
CompanyId INTEGER PRIMARY KEY NOT NULL,
global_duns_number INTEGER REFERENCES data(global_duns_number),
vendor_duns INTEGER REFERENCES data(vendor_duns),
CONSTRAINT unique_global UNIQUE (global_duns_number),
CONSTRAINT unique_dun UNIQUE (vendor_duns),
CONSTRAINT unique_vendor UNIQUE (global_duns_number, vendor_duns),
CONSTRAINT unique_vendor_reverse UNIQUE (vendor_duns, global_duns_number)
);
INSERT INTO company (global_duns_number, vendor_duns)
SELECT DISTINCT global_duns_number, vendor_duns
FROM data;
PRAGMA foreign_keys=on;
Where data is a raw csv import.
Consider I have a table:
create table product(id int8 not null, ... , primary key (id));
I have inserted some records, so 'product' is not empty.
Then I need another table:
create table order(id int8 not null, ..., primary key (id))
After that I decided to add connection between 'product' and 'order', in Order entity added:
#NotNull
#ManyToOne
private Product product;
So in sql I do following:
alter table order add column product int8 not null default (???);
alter table order add constraint FK_order_product foreign key (product) references product;
What should I write at (???)?
If I set default to 0, then SQL will expectedly complain like:
(Key product(0)) is not in the 'product' table
It looks like your order table is also not empty (if the table is empty it works fine). In your case I recommend you to add the field by executing
alter table order add column product int8 not null default 0;
then alter each row of the order table to make the correct references to the product table in the product field and finally add the Foreign Key constraint.
Also if your order table is populated with test data, you may just truncate it before executing your script, and you can use any default in this case or not use it at all.
How can you alter a table in MS Access using SQL to change a data type to AutoNumber?
I have tried to following with no success
ALTER TABLE PERSON ALTER COLUMN PERSON_ID Integer PRIMARY KEY counter
);
ALTER TABLE PERSON ALTER COLUMN PERSON_ID Integer PRIMARY KEY AUTONUMBER
);
ALTER TABLE PERSON ALTER COLUMN PERSON_ID Integer PRIMARY KEY AUTOINCREMENT
);
Each time I get the same issue "Syntax error" and it highlights the last word in the SQL.
For a Data Definition (DDL) query in Access you use COUNTER to define an AutoNumber field. You were trying to use both Integer and counter on the same field, and that won't work.
I just tried this and it worked for me in Access 2010:
ALTER TABLE PERSON ALTER COLUMN PERSON_ID COUNTER PRIMARY KEY
Note that in order for this statement to work
the table must be empty, and
the table must not already have a Primary Key, not even on the [PERSON_ID] field.
If the table already has rows in it then Access will not allow you to convert a Numeric (Long Integer) field to AutoNumber. In that case you need to create a new table with the AutoNumber Primary Key and then insert the rows from the old table into the new table.
For example, for an existing table named [PERSON] with columns
PERSON_ID INTEGER
PERSON_NAME TEXT(50)
you need to create a new table
CREATE TABLE PERSON_NEW (PERSON_ID COUNTER PRIMARY KEY, PERSON_NAME TEXT(50))
and then copy the records over
INSERT INTO PERSON_NEW
SELECT * FROM PERSON
I have to create a table (H2 embedded database) using fields from other tables. I decided to use CREATE TABLE AS statement.
My code:
CREATE TABLE DOC AS
SELECT I.ID, I.STATUS, A.REMINDERINFORMATION
FROM IE802 I JOIN IE802_ATTRIBUTES A ON A.IE802_ID=I.ID;
Each row which is generated from the code above additionally must have DOCID PrimaryKey. How can I add this column and make it autoincrement and PK at the same time?
Thanks for any tips and other solutions!
Alternatively, how can I make existing I.ID to be PK?
I'm still getting an error: Column "ID" must not be nullable; SQL statement:
ALTER TABLE DOC ADD PRIMARY KEY (ID) [90023-147]
H2 supports column definitions in CREATE AS SELECT:
CREATE TABLE DOC(
ID INT PRIMARY KEY,
STATUS INT,
REMINDERINFORMATION VARCHAR(255)
)
AS SELECT I.ID, I.STATUS, A.REMINDERINFORMATION
FROM IE802 I JOIN IE802_ATTRIBUTES A ON A.IE802_ID=I.ID;