Creating a table gives a "missing right parenthesis" error - sql

I have been getting error "ORA-00907: missing right parenthesis" when I run this create table statement:
create table employee(
primary key(emp_id number(20)),
emp_name varchar(30),
birth_date date CHECK(birth_date>18),
gender varchar(10),
dept_no number(20)
CONSTRAINT fk FOREIGN KEY(dept_no)
REFERENCES department(dept_no),
address varchar(50),
designation varchar(20)
CHECK(designation IN('manager', 'clerk', 'leader', 'analyst', 'designer', 'coder','tester')),
salary number(50)
CHECK(salary>0),
experience number(2),
email_id varchar(30)
CONSTRAINT chk_email
CHECK (REGEXP_LIKE(email_id,'^[A-Za-z0-9_.]+#[A-Za-z]+\.[A-Za-z]{2,4}$'))
);
I have looked up the exact syntax and after checking many times, everything seems to be just perfect but the error still exists. What is wrong?

A little bit of
invalid syntax (position of the primary key keywords),
superfluous foreign key keywords (you'd use them out of line, not inline),
check constraint for the birth_date column is wrong (how can date be larger than 18?),
Oracle suggests us to use varchar2 instead of varchar,
number(50) has too large precision (perhaps you'd rather just skip it).
Once fixed (with a dummy master table):
SQL> CREATE TABLE department
2 (
3 dept_no NUMBER PRIMARY KEY
4 );
Table created.
Employee:
SQL> CREATE TABLE employee
2 (
3 emp_id NUMBER (20) PRIMARY KEY,
4 emp_name VARCHAR2 (30),
5 birth_date DATE,
6 gender VARCHAR2 (10),
7 dept_no NUMBER CONSTRAINT fk_emp_dept REFERENCES department (dept_no),
8 address VARCHAR2 (50),
9 designation VARCHAR2 (20)
10 CHECK
11 (designation IN ('manager',
12 'clerk',
13 'leader',
14 'analyst',
15 'designer',
16 'coder',
17 'tester')),
18 salary NUMBER CHECK (salary > 0),
19 experience NUMBER (2),
20 email_id VARCHAR2 (30)
21 CONSTRAINT chk_email CHECK
22 (REGEXP_LIKE (
23 email_id,
24 '^[A-Za-z0-9_.]+#[A-Za-z]+\.[A-Za-z]{2,4}$'))
25 );
Table created.
SQL>
As of a trigger that checks employee's age, here's how:
SQL> CREATE OR REPLACE TRIGGER trg_bi_emp
2 BEFORE INSERT
3 ON employee
4 FOR EACH ROW
5 BEGIN
6 IF MONTHS_BETWEEN (SYSDATE, :new.birth_date) < 18 * 12
7 THEN
8 raise_application_error (-20000,
9 'Too young; must be at least 18 years of age');
10 END IF;
11 END;
12 /
Trigger created.
SQL> INSERT INTO employee (emp_id, birth_date) VALUES (1, DATE '2020-07-25');
INSERT INTO employee (emp_id, birth_date) VALUES (1, DATE '2020-07-25')
*
ERROR at line 1:
ORA-20000: Too young; must be at least 18 years of age
ORA-06512: at "SCOTT.TRG_BI_EMP", line 4
ORA-04088: error during execution of trigger 'SCOTT.TRG_BI_EMP'
SQL> INSERT INTO employee (emp_id, birth_date) VALUES (1, DATE '1997-07-25');
1 row created.
SQL>

Related

Problem inserting into table in oracle using PopSQL

The problem i'm having is that using PopSQL, when i insert something into a table it says success but then it inserts nothing into the table by saying 0 rows affected and i can't figure out what is the problem because PopSQL works fine with postgres and Mysql. Any help is much appreciated.
CREATE TABLE employees
(
employee_id NUMBER PRIMARY KEY,
first_name VARCHAR2(30) NOT NULL,
last_name VARCHAR2(30) NOT NULL,
hire_date DATE NOT NULL,
salary NUMBER(8,2) NOT NULL
);
INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
COMMIT;
SELECT * FROM employees;
Seem a Sys error to me
Try this :
INSERT INTO employees (employee_id, first_name, last_name, hire_date, salary)
VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
COMMIT;
SELECT * FROM employees;
Make sure to change the VALUES clause to match the correct number of columns and data types in the employees table.
As Jonas commented, "date" value (string, actually; you just enclosed some digits and letters into single quotes) looks suspicious. Read his comment once again.
I'm in Croatia. Let's see what happens in my database.
SQL> CREATE TABLE employees
2 (
3 employee_id NUMBER PRIMARY KEY,
4 first_name VARCHAR2(30) NOT NULL,
5 last_name VARCHAR2(30) NOT NULL,
6 hire_date DATE NOT NULL,
7 salary NUMBER(8,2) NOT NULL
8 );
Table created.
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000)
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
Error; can't say I didn't expect it. What does default NLS value (in my database) say about dates?
SQL> select sysdate right_now,
2 to_char(sysdate, 'dd-mon-yyyy') another_Format
3 from dual;
RIGHT_NOW ANOTHER_FORMAT
---------- --------------------
04.02.2023 04-vel-2023
SQL>
Right; format doesn't match, nor does the language. How to fix it?
One option is to use date literal instead of a string:
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', date '2010-01-01', 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ---------- ----------
100 Malik Makkes 01.01.2010 9000
SQL>
That works. Another option is to use to_date function with appropriate format model:
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes',
2 to_date('01-jan-2010', 'dd-mon-yyyy', 'nls_date_language = english'), 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ---------- ----------
100 Malik Makkes 01.01.2010 9000
SQL>
That works too. Yet another option is to alter your session (or, if you must, NLS settings for the whole database, but for that you'll need to talk to your DBA):
SQL> alter session set nls_date_format = 'dd-mon-yyyy';
Session altered.
SQL> alter session set nls_date_language = 'english';
Session altered.
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ----------- ----------
100 Malik Makkes 01-jan-2010 9000
SQL>
Works again.
Now you've seen a few valid ways to insert date value into a date datatype column. Pick one you find the most appropriate. My choice would be a date literal.
On the other hand, if that's not the issue, provide more info (illustrate execution of your code; post exact error you got).

No matter what data I insert into my table, the date stays the same at 03.01.2022. How can I fix this?

I created a primitive table in which I can store date, time, the id of a patient and the id of an employee.
CREATE TABLE Squedule (
id INTEGER,
datee DATE NOT NULL,
timee CHAR(5),
patientId CHAR(10),
employeeId CHAR(10),
CONSTRAINT squedule_pk PRIMARY KEY (kennzahl),
CONSTRAINT squedule_fkSprstdh FOREIGN KEY (employeeId) REFERENCES Sprechstdhilfe,
CONSTRAINT squedule_fkPatientIn FOREIGN KEY (patientId) REFERENCES PatientIn);
------------------I insert the data like so
INSERT INTO squedule(datee,timee,patientid,employeeid) VALUES('02.02.3000','16:43',8137770103,3146213220);
------------------This is the trigger for the id
CREATE TRIGGER newSquedule BEFORE INSERT ON Squedule
FOR EACH ROW
BEGIN
SELECT auto_increment_pk.NEXTVAL
INTO :new.id
FROM dual;
END;
This worked just fine until I noticed that no matter what data I try to insert for the datee value it always ends up with '03.01.2022' in the table for every single insert.
I dropped all tables and created them again a few times, because a few system_sequences got created, I guess because of an Identity I use in another table. But they did not get deleted with dropping every single table.
Maybe one of them is triggering something.
What can I do to solve this problem? I am clueless...
I can't reproduce what you're saying.
I removed foreign keys from the table (as I didn't feel like creating tables you reference).
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> CREATE SEQUENCE auto_increment_pk;
Sequence created.
SQL> CREATE TABLE squedule
2 (
3 id INTEGER,
4 datee DATE NOT NULL,
5 timee CHAR (5),
6 patientid CHAR (10),
7 employeeid CHAR (10),
8 CONSTRAINT squedule_pk PRIMARY KEY (id)
9 );
Table created.
SQL> CREATE OR REPLACE TRIGGER newsquedule
2 BEFORE INSERT
3 ON squedule
4 FOR EACH ROW
5 BEGIN
6 :new.id := auto_increment_pk.NEXTVAL;
7 END;
8 /
Trigger created.
Inserts:
SQL> INSERT INTO squedule (datee,
2 timee,
3 patientid,
4 employeeid)
5 VALUES ('02.02.3000',
6 '16:43',
7 8137770103,
8 3146213220);
1 row created.
But, the way you put it, I can insert anything into the timee column, including such a rubbish:
SQL> INSERT INTO squedule (datee,
2 timee,
3 patientid,
4 employeeid)
5 VALUES ('25.02.3000',
6 'xy:83',
7 8137770103,
8 3146213220);
1 row created.
Result:
SQL> SELECT * FROM squedule;
ID DATEE TIMEE PATIENTID EMPLOYEEID
---------- ------------------- ----- ---------- ----------
1 02.02.3000 00:00:00 16:43 8137770103 3146213220 --> 02.02.3000, not 03.01.2022
2 25.02.3000 00:00:00 xy:83 8137770103 3146213220 --> invalid time value
SQL>
I suggest you abandon what you're doing and use only one column whose datatype is DATE as - in Oracle - it contains both date and time component. Something like this:
SQL> DROP TABLE squedule;
Table dropped.
SQL> CREATE TABLE squedule
2 (
3 id INTEGER,
4 datee DATE NOT NULL,
5 patientid CHAR (10),
6 employeeid CHAR (10),
7 CONSTRAINT squedule_pk PRIMARY KEY (id)
8 );
Table created.
SQL> CREATE OR REPLACE TRIGGER newsquedule
2 BEFORE INSERT
3 ON squedule
4 FOR EACH ROW
5 BEGIN
6 :new.id := auto_increment_pk.NEXTVAL;
7 END;
8 /
Trigger created.
Insert:
SQL> INSERT INTO squedule (datee, patientid, employeeid)
2 VALUES (TO_DATE ('02.02.3000 14:43', 'dd.mm.yyyy hh24:mi'),
3 8137770103,
4 3146213220);
1 row created.
SQL> SELECT * FROM squedule;
ID DATEE PATIENTID EMPLOYEEID
---------- ------------------- ---------- ----------
3 02.02.3000 14:43:00 8137770103 3146213220
SQL>

Show film description with string format

I have a task need to write a trigger statement with format
This is my database schema:
I write my code like
CREATE OR REPLACE TRIGGER "BI_FILM_DESP"
BEFORE INSERT ON "FILM"
FOR EACH ROW
DECLARE
RatingFilm VARCHAR2(8);
Seq NUMBER(3);
OriginalL VARCHAR2(20);
Language VARCHAR2(20);
BEGIN
SELECT RATING INTO RatingFilm FROM FILM F;
SELECT COUNT(RATING) INTO Seq FROM FILM F GROUP BY F.RATING;
SELECT LANGUAGE.NAME INTO OriginalL FROM LANGUAGE L WHERE (L.LANGUAGE_ID =: FILM.LANGUAGE_ID);
SELECT LANGUAGE.NAME INTO Language FRoM LANGUAGE L WHERE (L.LANGUAGE_ID =: FILM.LANGUAGE_ID);
SELECT CONCAT(RatingFilm, "-", Seq, ": Originally in", OriginalL, ". Re-released in ", Language, ".");
END;
/
However it shows error
I think it's hard to read those errors and I need some help to correct it. Thanks in advance.
Edit: Add code that create tables
CREATE TABLE film (
film_id NUMBER(5) NOT NULL,
title varchar2(255),
description varchar2(255),
release_year NUMBER(4) DEFAULT NULL,
language_id NUMBER(3) NOT NULL,
original_language_id NUMBER(3) DEFAULT NULL,
rental_duration NUMBER(3) DEFAULT 3 NOT NULL,
rental_rate NUMBER(4,2) DEFAULT '4.99' NOT NULL,
length NUMBER(5) DEFAULT NULL,
replacement_cost NUMBER(5,2) DEFAULT '19.99' NOT NULL,
rating varchar2(8) DEFAULT 'G' NOT NULL,
special_features varchar2(255) DEFAULT NULL
);
CREATE TABLE language (
language_id NUMBER(3) NOT NULL,
name varchar2(20)
);
I hope you read astentx's comment.
Here's how you could/should do it.
Tables involved (with necessary columns only):
SQL> CREATE TABLE language
2 (
3 language_id NUMBER PRIMARY KEY,
4 name VARCHAR2 (20)
5 );
Table created.
SQL> INSERT INTO language (language_id, name)
2 SELECT 1, 'English' FROM DUAL
3 UNION ALL
4 SELECT 2, 'Croatian' FROM DUAL;
2 rows created.
SQL> CREATE TABLE film
2 (
3 film_id NUMBER PRIMARY KEY,
4 title VARCHAR2 (20),
5 description VARCHAR2 (100),
6 language_id NUMBER REFERENCES language,
7 original_language_id NUMBER REFERENCES language,
8 rating NUMBER
9 );
Table created.
Trigger: don't select from table on which that row-level trigger fires as you'd get mutating table error. Good for you, you don't have to do that - use :new pseudorecord values instead:
SQL> CREATE OR REPLACE TRIGGER bi_film_desp
2 BEFORE INSERT
3 ON film
4 FOR EACH ROW
5 DECLARE
6 l_language language.name%TYPE;
7 l_original_language language.name%TYPE;
8 BEGIN
9 SELECT l.name
10 INTO l_language
11 FROM language l
12 WHERE l.language_id = :new.language_id;
13
14 SELECT l.name
15 INTO l_original_language
16 FROM language l
17 WHERE l.language_id = :new.original_language_id;
18
19 :new.description :=
20 'Rating: '
21 || :new.rating
22 || ', original language: '
23 || l_original_language
24 || ', language: '
25 || l_language;
26 END;
27 /
Trigger created.
SQL>
Let's test it:
SQL> INSERT INTO film (film_id,
2 title,
3 language_id,
4 original_language_id,
5 rating)
6 VALUES (1,
7 'Izbavitelj',
8 1,
9 2,
10 7);
1 row created.
Result:
SQL> select title, description, rating from film;
TITLE DESCRIPTION RATING
---------- ------------------------------------------------------------ ----------
Izbavitelj Rating: 7, original language: Croatian, language: English 7
SQL>
Looks OK to me.

Inserting random from a given string

My purpose is to write an insert statement that adds a random value from a given string, more specifically if the person is married, single or a widower. I needed to first populate my table with hundreds of random entries because I need to run Autotrace on it and check its optimization. In any event, I first created the table, then populated all the columns, except for the one concerning marital status. Then I wanted to write a different INSERT statement just for that because I thought it might be easier then putting it into the plSQL block I made to populate the table. Here is my code:
create table employees(
id_employee integer not null,
name varchar2(50) not null,
surname varchar2(50) not null,
marital_status varchar2(50),
birthday date);
ALTER TABLE employees ADD CONSTRAINT employees_pk PRIMARY KEY ( id_employee );
declare
id_employee integer:= 1;
begin
while id_employee <= 20 loop
insert into employees values (id_employee, dbms_random.string('l', 10), dbms_random.string('l', 10), null, TO_DATE(
TRUNC(
DBMS_RANDOM.VALUE(TO_CHAR(DATE '2016-01-01','J')
,TO_CHAR(DATE '2020-12-31','J')
)
),'J'
));
id_employee:= id_employee + 1;
end loop;
end;
Now that I've managed this and it worked, I just need to create an INSERT statement to basically modify the null value that is on every entry's marital_status column. But as I stated earlier, I want to have a statement that will return either (married, single, widower). Can this be achieved? Or is it not possible to give a command to extract a random value from a given string?
If I understood you correctly, you don't need PL/SQL at all - everything can be done in a single insert statement (or select, if you prefer). Here's how:
SQL> CREATE TABLE employees
2 (
3 id_employee INTEGER PRIMARY KEY,
4 name VARCHAR2 (50) NOT NULL,
5 surname VARCHAR2 (50) NOT NULL,
6 marital_status VARCHAR2 (50),
7 birthday DATE
8 );
Table created.
SQL> CREATE SEQUENCE seqes;
Sequence created.
Insert sample rows:
SQL> INSERT INTO employees (id_employee,
2 name,
3 surname,
4 marital_status,
5 birthday)
6 SELECT seqes.NEXTVAL id_employee,
7 DBMS_RANDOM.string ('l', 10) name,
8 DBMS_RANDOM.string ('l', 10) surname,
9 --
10 CASE
11 WHEN MOD (seqes.NEXTVAL, 3) = 0 THEN 'single'
12 WHEN MOD (seqes.NEXTVAL, 2) = 0 THEN 'married'
13 ELSE 'widower'
14 END marital_status,
15 --
16 TO_DATE (
17 TRUNC (
18 DBMS_RANDOM.VALUE (TO_CHAR (DATE '2016-01-01', 'J'),
19 TO_CHAR (DATE '2020-12-31', 'J'))),
20 'J') birthda
21 FROM DUAL
22 CONNECT BY LEVEL <= 20;
20 rows created.
Result:
SQL> SELECT * FROM employees;
ID_EMPLOYEE NAME SURNAME MARITAL_STATUS BIRTHDAY
----------- ------------ ------------ --------------- ----------
1 cpewxypfop urkqkpapdk widower 22.12.2018
2 qjslhprqxf jxoaennyqe married 27.08.2017
3 jjwknqkcel zkmnwtoovv single 25.10.2018
4 levwydigey numbxjvjtc married 12.02.2019
5 hswtiotjin cjdfiastvi widower 30.01.2019
6 yxahvjfmre dnlfmkphmv single 11.08.2017
7 nctcntredz raqpofzufx widower 29.05.2018
8 wyivovpnoc ikjakuzanf married 19.09.2016
9 rvtbqfgqnu iuqjqosait single 28.07.2018
10 oislloosfy xtfxpnceik married 30.03.2020
11 issbxtldsn bovdghpjke widower 21.09.2018
12 gzgjdlvwcw rmfqglwohc single 11.12.2019
13 utbznnyyhs ojcswdwuvh widower 21.12.2019
14 etsvhavose fypgntictn married 23.03.2018
15 myjijmagej lvmpbcvcfc single 12.09.2016
16 givwwayxkf hgemcfvnff married 13.02.2016
17 nquarbpzlf zwgjukhgxg widower 07.09.2018
18 lnyyrkohac ttygaxmvle single 25.05.2020
19 gmqboujcbb qszmifozcs widower 20.09.2019
20 eegwdvqvld dsembshumq married 04.09.2020
20 rows selected.
SQL>

PL/SQL creating a trigger problems

I have to create a trigger on an Employee table. If an INSERT or UPDATE statement is issued for the Employee table the trigger launches and makes sure that the value of 'salary' field meets the criteria in the job_min_sal table. After trying over and over I got a mutating table error and now am very frustrated and don't know what to do.
JOB_MIN_SALARY TABLE:
JOB VARCHAR2(50) PRIMARY KEY
MIN_SAL NUMBER(7,2) NOT NULL
The JOB_MIN_SAL table is populated with a variety of job titles and salaries. I am confused working with my trigger and wondering if I could get some assistance where to go from here
CREATE OR REPLACE TRIGGER employee_job_salary
BEFORE INSERT OR UPDATE OF SALARY on employee
FOR EACH ROW
DECLARE
v_salary NUMBER;
BEGIN
SELECT minimum_salary
INTO v_salary
FROM job_min_salary
WHERE UPPER(job) = UPPER(:NEW.job);
I know I am really far off I am just looking for help as for what this requires and what steps I need to take to get this. Thanks!
The EMPLOYEE table:
(
EMPLOYEE_ID NUMBER(4)
EMPLOYEE_NAME VARCHAR2(20)
JOB VARCHAR2(50)
MANAGER_ID NUMBER(4)
HIRE_DATE DATE
SALARY NUMBER(9)
COMMISION NUMBER(9)
DEPARTMENT_ID NUMBER(4)
);
i am supposing you are doing something like
comparing new salary with min salary criterion and update only if :new.SALARY >= v_salary
what are you doing if this is not met, are u trapping an exception or just ignoring the error or returning an error code to debug.
post more info
CREATE TABLE job_min_salary
(
job VARCHAR2(50) PRIMARY KEY,
min_sal NUMBER(7,2) NOT NULL
);
INSERT INTO job_min_salary VALUES('CEO','100');
-- 1 rows inserted.
CREATE TABLE employee
(
employee_id NUMBER(4),
employee_name VARCHAR2(20),
job VARCHAR2(50),
manager_id NUMBER(4),
hire_date DATE,
salary NUMBER(9),
commision NUMBER(9),
department_id NUMBER(4)
);
INSERT INTO employee VALUES(1, 'Name', 'CEO', 1, TO_DATE('2000-01-01', 'YYYY-MM-DD'), 80, 80, 1);
-- 1 rows inserted.
CREATE OR REPLACE TRIGGER employee_job_salary
BEFORE INSERT OR UPDATE OF salary ON employee
FOR EACH ROW
DECLARE
v_salary NUMBER(1);
BEGIN
SELECT 1
INTO v_salary
FROM job_min_salary
WHERE UPPER(job) = UPPER(:NEW.job)
AND :NEW.salary >= min_sal;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20999, 'Salary value is too low for given job');
END;
-- TRIGGER EMPLOYEE_JOB_SALARY compiled
SELECT * FROM employee;
-- 1 Name CEO 1 2000-01-01 00:00:00 80 80 1
UPDATE employee
SET salary = 10
WHERE job = 'CEO';
-- ORA-20999: Salary value is too low for given job
UPDATE employee
SET salary = 100
WHERE job = 'CEO';
-- 1 rows updated.
SELECT * FROM employee;
-- 1 Name CEO 1 2000-01-01 00:00:00 100 80 1