-- Trying to sort data using ORDER by with 2 SUBSTITUTION VARIABLE , but not working , problem is included below the thread.
Table: users
CREATE TABLE users
(
user_id VARCHAR(5) ,
user_name VARCHAR(30),
CONSTRAINT pk_users PRIMARY KEY(user_id)
)
/
INSERT INTO users
VALUES ('U01','User1')
/
INSERT INTO users
VALUES ('U02','User2')
/
Table: staffaccount
CREATE TABLE staffaccount
(
staffaccount_id VARCHAR(5) ,
user_id VARCHAR(5) ,
CONSTRAINT pk_staffaccount PRIMARY KEY(staffaccount_id),
CONSTRAINT fk_staffaccount1 FOREIGN KEY (user_id) REFERENCES users(user_id)
)
/
INSERT INTO staffaccount
VALUES ('STF01','U01')
/
INSERT INTO staffaccount
VALUES ('STF02','U02')
/
Table: location
CREATE TABLE location
(
location_id VARCHAR(5),
location_name VARCHAR(25) NOT NULL,
CONSTRAINT pk_location PRIMARY KEY(location_id)
)
/
INSERT INTO location
VALUES ('LOC01','Staff Toilet')
/
INSERT INTO location
VALUES ('LOC02','Staff Office')
/
INSERT INTO location
VALUES ('LOC03','Staff Meeting Room')
/
INSERT INTO location
VALUES ('LOC04','Staff Hall')
/
Table: bookingstaff
CREATE TABLE bookingstaff
(
staffaccount_id VARCHAR(5),
location_id VARCHAR(5),
timebooked TIMESTAMP,
usages VARCHAR(25)
)
/
INSERT INTO bookingstaff
VALUES ('STF01','LOC01',TIMESTAMP'2018-01-01 10:00:00','Pee')
/
INSERT INTO bookingstaff
VALUES ('STF02','LOC02',TIMESTAMP'2018-01-02 10:00:00','Writing')
/
INSERT INTO bookingstaff
VALUES ('STF01','LOC03',TIMESTAMP'2018-01-05 10:00:00','Meeting')
/
INSERT INTO bookingstaff
VALUES ('STF02','LOC04',TIMESTAMP'2018-01-12 10:00:00','Dancing')
/
INSERT INTO bookingstaff
VALUES ('STF01','LOC02',TIMESTAMP'2018-02-01 10:00:00','Writing')
/
INSERT INTO bookingstaff
VALUES ('STF02','LOC03',TIMESTAMP'2018-02-02 10:00:00','Meeting')
/
INSERT INTO bookingstaff
VALUES ('STF01','LOC02',TIMESTAMP'2018-02-15 10:00:00','Writing')
/
INSERT INTO bookingstaff
VALUES ('STF02','LOC04',TIMESTAMP'2018-03-01 10:00:00','Dancing')
/
INSERT INTO bookingstaff
VALUES ('STF01','LOC03',TIMESTAMP'2018-03-02 10:00:00','Meeting')
/
On the above is all my table query, try to use substitution variable
to display data. Code below
SELECT u.user_name,l.location_name,b.usages,to_char(cast(b.timebooked as date),'DD-MM-YYYY')as "DATE"
FROM staffaccount s
JOIN bookingstaff b
ON b.staffaccount_id = s.staffaccount_id
LEFT OUTER JOIN users u
ON u.user_id= s.user_id
LEFT OUTER JOIN location l
ON l.location_id= b.location_id
WHERE l.location_name LIKE '%Staff%'
AND timebooked
BETWEEN date&
AND date&
with the code, here is the result for it. (first substitution
variable: '2017-01-01' , second substitution variable:'2018-02-10')
http://prntscr.com/iztftx < Result displayed with myOra
But when i tried to add ORDER by usages, it will show error.
Error:
Never allowing me to enter second substitution variable
should be &var and not var&
WHERE l.location_name LIKE '%Staff%'
AND timebooked BETWEEN &date AND &date
ORDER BY usages
and for a better readiblity
WHERE l.location_name LIKE '%Staff%'
AND timebooked BETWEEN &date1 AND &date2
ORDER BY usages
Related
I'm transferring data from Oracle.
There is table named A and when there are overlapping columns in the process of moving them to table C, I am trying to delete them and put them in.
However, if A and C have the same column configuration, it works smoothly, but the column configuration is different, so I don't know what to do if I convert it.
What I've tried so far is as follows.
CREATE TABLE test.test_pk_a
(
col_one VARCHAR2(4) NOT NULL,
col_two VARCHAR2(5) NOT NULL,
col_three VARCHAR2(8) NOT NULL,
CONSTRAINT test_pk_a_pk PRIMARY KEY(col_one,col_two)
);
INSERT INTO test_pk_a VALUES('A',1,1);
INSERT INTO test_pk_a VALUES('A',2,1);
INSERT INTO test_pk_a VALUES('A',3,1);
CREATE TABLE test.test_pk_c
(
col_one_v VARCHAR2(4) NOT NULL,
col_two_v VARCHAR2(5) NOT NULL,
col_three_v VARCHAR2(8) NOT NULL,
CONSTRAINT test_pk_c_pk PRIMARY KEY(col_one_v,col_two_v)
);
INSERT INTO test_pk_c VALUES(10,'c',1);
INSERT INTO test_pk_c VALUES(20,'a',1);
DELETE
FROM (SELECT *
FROM test.test_pk_a A, test.test_pk_c C
WHERE A.col_two*10 = C.col_one_v
AND LOWER(A.col_one)= C.col_two_v);
How should I modify this Query in order to make it work?
If you've meant to delete from the table A, then you can precede the subquery with EXISTS such as
DELETE test_pk_a
WHERE EXISTS (SELECT 0
FROM test_pk_a A
JOIN test_pk_c C
ON A.col_two * 10 = C.col_one_v
AND LOWER(A.col_one) = C.col_two_v);
if you meant the common column names by configuration wouldn't be the case(no problem whether to have the same column names or not)
I'm on Oracle Database 18c Express Edition and APEX 19.1.
The requirement is to be able to link between items with same or different types:
logs with logs,
events with logs
...and so on.
e.g.
logs.item_id = 1
logs.item_id = 2
events.item_id = 5
logs.item_id = 2
logs.item_id = 1
events.item_id = 5
logs.item_id = 1
My idea is to have a shared ID sequence, that would be populated with every insert on - for example - logs table.
Having unique IDs for logs, events and other items, I could create links in separate links table
https://imgur.com/Dchz7De.jpg
After executing DDL script, my first
INSERT INTO events (dummy) VALUES ('D');
results with an error.
ORA-02291: integrity constraint (C##TEST.EVE_ITE_FK_1) violated - parent key not found
Following inserts assign sequence values starting from 3.
https://imgur.com/ru2aewG.jpg
DROP TABLE items CASCADE CONSTRAINTS;
DROP TABLE logs CASCADE CONSTRAINTS;
DROP TABLE events CASCADE CONSTRAINTS;
DROP TABLE links CASCADE CONSTRAINTS;
DROP SEQUENCE items_seq;
DROP TRIGGER logs_trg;
DROP TRIGGER events_trg;
/
CREATE TABLE logs (
item_id NUMBER(*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE events (
item_id NUMBER (*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE links (
id NUMBER(*,0) GENERATED ALWAYS AS IDENTITY PRIMARY KEY
,item_id_1 NUMBER(*,0)
,item_id_2 NUMBER(*,0));
/
CREATE TABLE items (
id NUMBER(*,0) PRIMARY KEY
,type CHAR(1 CHAR));
/
ALTER TABLE logs ADD CONSTRAINT log_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE events ADD CONSTRAINT eve_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_1 FOREIGN KEY (item_id_1) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_2 FOREIGN KEY (item_id_2) REFERENCES items (id);
/
CREATE SEQUENCE items_seq START WITH 1;
/
CREATE OR REPLACE TRIGGER logs_trg FOR INSERT ON logs
COMPOUND TRIGGER
l_item_id PLS_INTEGER := items_seq.nextval;
co_item_type CONSTANT CHAR(1) := 'L';
BEFORE STATEMENT
IS
BEGIN
INSERT INTO items(id
,type)
VALUES (l_item_id
,co_item_type);
END BEFORE STATEMENT;
BEFORE EACH ROW
IS
BEGIN
SELECT l_item_id
INTO :NEW.item_id
FROM dual;
END BEFORE EACH ROW;
END;
/
CREATE OR REPLACE TRIGGER events_trg FOR INSERT ON events
COMPOUND TRIGGER
l_item_id PLS_INTEGER := items_seq.nextval;
co_item_type CONSTANT CHAR(1) := 'E';
BEFORE STATEMENT
IS
BEGIN
INSERT INTO items(id
,type)
VALUES (l_item_id
,co_item_type);
END BEFORE STATEMENT;
BEFORE EACH ROW
IS
BEGIN
SELECT l_item_id
INTO :NEW.item_id
FROM dual;
END BEFORE EACH ROW;
END;
/
Do you have any suggestions on what could I do to make it work with the 1st insert?
I expect
INSERT INTO events (dummy) VALUES ('D');
to produce items.id = 1 and events.item_id = 1.
EDIT:
Following Enrique's advice, I switched to non-compound trigger with returning clause - as below.
DROP TABLE items CASCADE CONSTRAINTS;
DROP TABLE logs CASCADE CONSTRAINTS;
DROP TABLE events CASCADE CONSTRAINTS;
DROP TABLE links CASCADE CONSTRAINTS;
DROP SEQUENCE items_seq;
/
CREATE TABLE logs (
item_id NUMBER(*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE events (
item_id NUMBER (*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE links (
id NUMBER(*,0) GENERATED ALWAYS AS IDENTITY PRIMARY KEY
,item_id_1 NUMBER(*,0)
,item_id_2 NUMBER(*,0));
/
CREATE TABLE items (
id NUMBER(*,0) PRIMARY KEY
,type CHAR(1 CHAR));
/
ALTER TABLE logs ADD CONSTRAINT log_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE events ADD CONSTRAINT eve_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_1 FOREIGN KEY (item_id_1) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_2 FOREIGN KEY (item_id_2) REFERENCES items (id);
/
CREATE SEQUENCE items_seq START WITH 1;
/
CREATE OR REPLACE TRIGGER logs_trg FOR INSERT ON logs
COMPOUND TRIGGER
l_item_id PLS_INTEGER := items_seq.nextval;
co_item_type CONSTANT CHAR(1) := 'L';
BEFORE STATEMENT
IS
BEGIN
INSERT INTO items(id
,type)
VALUES (l_item_id
,co_item_type);
END BEFORE STATEMENT;
BEFORE EACH ROW
IS
BEGIN
SELECT l_item_id
INTO :NEW.item_id
FROM dual;
END BEFORE EACH ROW;
END;
/
CREATE OR REPLACE TRIGGER events_trg BEFORE INSERT ON events
FOR EACH ROW
DECLARE
co_item_type CONSTANT CHAR(1) := 'M';
BEGIN
INSERT INTO items(id
,type)
VALUES (items_seq.nextval
,co_item_type)
RETURNING id INTO :NEW.item_id;
DBMS_OUTPUT.PUT_LINE(systimestamp);
END;
/
INSERT INTO events (dummy) values ('D');
INSERT INTO events (dummy) values ('D');
Now the problem is different. The 1st insert on events table generates 2 values on items_seq
INSERT INTO events (dummy) VALUES ('D');
DBMS_OUTPUT:
08-MAY-19 11.08.29.301000000 +02:00
08-MAY-19 11.08.29.303000000 +02:00
Ongoing inserts behave as expected - 1 seq number for each insert. So 2 inserts generate 3 sequence values.
My desired outcome is to have items.id = 1 for first insert on events table.
Just use this
v_myid number;
insert into table(col1, col2)
values(value1, value2)
returning id into v_myid;
I have a trigger named tr_admin_user_role that automatically insert values into tbl_user_role table when we perform a insert in another table called tbl_admin. There is no error at compile time but whenever I insert a value into tbl_admin table it shows me an error and error is like
This is my tbl_admin table
CREATE TABLE tbl_admin(
admin_id INTEGER,
username VARCHAR2(50) NOT NULL UNIQUE,
passwords VARCHAR2(50) NOT NULL,
email VARCHAR2(100) UNIQUE,
enabled CHAR(1) DEFAULT 1 NOT NULL,
created_at DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT pk_admin_id PRIMARY KEY(admin_id)
);
tbl_user_role table
CREATE TABLE tbl_user_role(
user_role_id INTEGER,
username VARCHAR2(50) NOT NULL,
user_role VARCHAR2(50) DEFAULT 'ROLE_ADMIN' NOT NULL,
CONSTRAINT pk_user_role_id PRIMARY KEY(user_role_id)
);
Trigger that i have created
CREATE OR REPLACE TRIGGER tr_admin_user_role
AFTER INSERT ON tbl_admin
FOR EACH ROW
DECLARE
new_username TBL_ADMIN.username%TYPE;
BEGIN
SELECT username INTO new_username FROM (
SELECT username FROM tbl_admin ORDER BY username DESC
) WHERE ROWNUM = 1;
INSERT INTO tbl_user_role(username, user_role) VALUES(new_username, 'ROLE_ADMIN');
END;
Insert statement
INSERT INTO tbl_admin(username, passwords) VALUES('nisha', 'nisha');
That's not how you fetch the newly inserted / updated / previous value of a column in a Trigger. You should use the :OLD.column_name and :NEW.column_name to refer the old and new column values.Read the documentation to understand more.
So, your Trigger could be rewritten as
CREATE OR REPLACE TRIGGER tr_admin_user_role AFTER
INSERT ON tbl_admin
FOR EACH ROW
BEGIN
INSERT INTO tbl_user_role (
username,
user_role
) VALUES (
:NEW.username,
'ROLE_ADMIN'
);
END;
/
I assume you are using another trigger to generate
admin_id and user_role_id since they are declared as PRIMARY KEYs
and you are not including them in your inserts.
Db fiddle demo
Here I've used dummy values for those columns.
I have 3 tables in my database namely employees,students and Images
create table employees(id number primary key,name varchar2(100), address varchar2(100));
create table students(id number primary key,name varchar2(100),address varchar2(100));
create table Images (image_id number primary key,employee_id number,student_id number,image_name varchar2(100));
Insert into employees values (1,'asdfasd','asdfasdf');
Insert into employees values (2,'asdfasd','asdfasdf');
Insert into employees values (3,'asdfasd','asdfasdf');
Insert into employees values (4,'asdfasd','asdfasdf');
Insert into employees values (5,'asdfasd','asdfasdf');
Insert into students values (1,'asdfasd','asdfasdf');
Insert into students values (2,'asdfasd','asdfasdf');
Insert into students values (3,'asdfasd','asdfasdf');
Insert into students values (4,'asdfasd','asdfasdf');
Insert into students values (5,'asdfasd','asdfasdf');
Insert into students values (49,'asdfasd','asdfasdf');
Insert into Images(image_id,employee_id,image_name) values (1,5,'adsfasdfasdf');
Insert into Images(image_id,student_id,image_name) values (2,49,'asfasdfasdf');
Now, when Inserting a row into the Images table I should check whether the employee_id / Student_id is existed in the employees table/student table, If a match found then only I have to Insert else it should not.
I thought of adding two foreign keys on the images table as follows:
alter table images add constraint fk_employeeid foreign key(employee_id)
references employees(id);
alter table images add constraint fk_studentsid foreign key(student_id)
references students(id);
But, If I do so. It will not allow me to insert null values. How can I modify my design so that whenever I insert a row in images table either it should be an employee_id or an student_id.
If I created any confusion, here is the link for the sql fiddle,http://www.sqlfiddle.com/#!4/92d24/1/0
I thought of adding two foreign keys on the images table.
But, If I do so. It will not allow me to insert null values.
You are wrong when you say the foreign key constraint won't allow NULL values. It will definitely allow the NULL values.
Test case
Let's add the foreign key constraint on the IMAGES table for the employee_id and student_id.
ALTER TABLE images ADD CONSTRAINT fk_emp FOREIGN KEY(employee_id) REFERENCES employees(ID);
ALTER TABLE images ADD CONSTRAINT fk_stu FOREIGN KEY(student_id) REFERENCES students(ID);
Let's check the INSERT with NULL values:
SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,5,'adsfasdfasdf');
1 row created.
SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (2,49,'asfasdfasdf');
1 row created.
SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (3,null,'adsfasdfasdf');
1 row created.
SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (4,null,'asfasdfasdf');
1 row created.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
SQL> SELECT * FROM images;
IMAGE_ID EMPLOYEE_ID STUDENT_ID IMAGE_NAME
---------- ----------- ---------- ---------------
1 5 adsfasdfasdf
2 49 asfasdfasdf
3 adsfasdfasdf
4 asfasdfasdf
SQL>
Let's check the foreign key constraint validation:
SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,10,'adsfasdfasdf');
INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,10,'adsfasdfasdf')
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.SYS_C0010739) violated
SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (2,20,'asfasdfasdf');
INSERT INTO Images(image_id,student_id,image_name) VALUES (2,20,'asfasdfasdf')
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.SYS_C0010739) violated
SQL>
So, everything works as per the design.
Add constraints to images like you did. Add one more constraint:
alter table images add constraint chk_nulls
check (
(employee_id is not null and student_id is null)
or (employee_id is null and student_id is not null)
);
This way you cannot insert both nulls nor both not nulls for employee_id and student_id. And foreign keys are also checked.
Test:
insert into images values (1, 1, null, 'not important'); -- OK
insert into images values (2, null, null, 'not important'); -- error
insert into images values (3, 1, 1, 'not important'); -- error
insert into images values (4, null, 1, 'not important'); -- OK
I would keep the foreign keys, that is the correct approach.
But instead of inserting NULL's, you should define an "unknown record" in your EMPLOYEES and STUDENTS tables (maybe with an id=-1, name='UNKNOWN'), and insert -1 into your IMAGES table.
I recommend you to change the primary key in table images, and have as PK three columns (image_id, employee_id and student_id).
Edit 1: Based on comment
I think you planned in a wrong way the problem. If the images are for both, employees and students, you should have two tables, images_employees and images_students, with respectively foreign keys employee_id and student_id and of course an id for the image.
But is there any sense to have a row like this?
id: 1 student_id: null image_name: 'something'
I don't think so... please explain more about the purpose of images table.
This question already has answers here:
How to create id with AUTO_INCREMENT on Oracle?
(18 answers)
Closed 8 years ago.
I am facing issue while inserting multiple row in one go into table because column id has primary key and its created based on sequence.
for ex:
create table test (
iD number primary key,
name varchar2(10)
);
insert into test values (123, 'xxx');
insert into test values (124, 'yyy');
insert into test values (125, 'xxx');
insert into test values (126, 'xxx');
The following statement creates a constraint violoation error:
insert into test
(
select (SELECT MAX (id) + 1 FROM test) as id,
name from test
where name='xxx'
);
This query should insert 3 rows in table test (having name=xxx).
You're saying that your query inserts rows with primary key ID based on a sequence. Yet, in your insert/select there is select (SELECT MAX (id) + 1 FROM test) as id, which clearly is not based on sequence. It may be the case that you are not using the term "sequence" in the usual, Oracle way.
Anyway, there are two options for you ...
Create a sequence, e.g. seq_test_id with the starting value of select max(id) from test and use it (i.e. seq_test_id.nextval) in your query instead of the select max(id)+1 from test.
Fix the actual subselect to nvl((select max(id) from test),0)+rownum instead of (select max(id)+1 from test).
Please note, however, that the option 2 (as well as your original solution) will cause you huge troubles whenever your code runs in multiple concurrent database sessions. So, option 1 is strongly recommended.
Use
insert into test (
select (SELECT MAX (id) FROM test) + rownum as id,
name from test
where name='xxx'
);
as a workaround.
Of course, you should be using sequences for integer-primary keys.
If you want to insert an ID/Primary Key value generated by a sequence you should use the sequence instead of selecting the max(ID)+1.
Usually this is done using a trigger on your table wich is executed for each row. See sample below:
CREATE TABLE "MY_TABLE"
(
"MY_ID" NUMBER(10,0) CONSTRAINT PK_MY_TABLE PRIMARY KEY ,
"MY_COLUMN" VARCHAR2(100)
);
/
CREATE SEQUENCE "S_MY_TABLE"
MINVALUE 1 MAXVALUE 999999999999999999999999999
INCREMENT BY 1 START WITH 10 NOCACHE ORDER NOCYCLE NOPARTITION ;
/
CREATE OR REPLACE TRIGGER "T_MY_TABLE"
BEFORE INSERT
ON
MY_TABLE
REFERENCING OLD AS OLDEST NEW AS NEWEST
FOR EACH ROW
WHEN (NEWEST.MY_ID IS NULL)
DECLARE
IDNOW NUMBER;
BEGIN
SELECT S_MY_TABLE.NEXTVAL INTO IDNOW FROM DUAL;
:NEWEST.MY_ID := IDNOW;
END;
/
ALTER TRIGGER "T_MY_TABLE" ENABLE;
/
insert into MY_TABLE (MY_COLUMN) values ('DATA1');
insert into MY_TABLE (MY_COLUMN) values ('DATA2');
insert into MY_TABLE (MY_ID, MY_COLUMN) values (S_MY_TABLE.NEXTVAL, 'DATA3');
insert into MY_TABLE (MY_ID, MY_COLUMN) values (S_MY_TABLE.NEXTVAL, 'DATA4');
insert into MY_TABLE (MY_COLUMN) values ('DATA5');
/
select * from MY_TABLE;