ORA-01858 FOR BEGINNER - sql

CREATE TABLE Pizza
(
pizza_id DECIMAL(12) NOT NULL PRIMARY KEY,
name VARCHAR(32) NOT NULL,
date_available DATE NOT NULL,
price DECIMAL(4,2) NOT NULL
);
CREATE TABLE Topping
(
topping_id DECIMAL(12) NOT NULL,
topping_name VARCHAR(64) NOT NULL,
pizza_id DECIMAL(12)
);
ALTER TABLE Topping
ADD CONSTRAINT topping_pk PRIMARY KEY(topping_id);
ALTER TABLE Topping
ADD CONSTRAINT Topping_pizza_fk
FOREIGN KEY(pizza_id) REFERENCES Pizza(pizza_id);
INSERT INTO pizza (pizza_id, name, date_available, price)
VALUES (1, 'Plain', CAST('27-Feb-2021' AS DATE), 6);
Error:
ORA-01858: a non-numeric character was found where a numeric was expected
I cannot figure out which part is wrong, I'm just a beginner for SQL, it seems related with date, can someone help me?

This works for me: SQL Fiddle. Don't use CAST to convert strings to dates. That's the only thing that looks off about your example. It may be using a different default date format than your string. Instead use TO_DATE( '27-Feb-2021', 'DD-Mon-YYYY') which converts a string to a date, or DATE '2021-02-27', which is a date literal and only takes the yyyy-mm-dd format.
Additionally, I'd suggest using NUMBER instead of DECIMAL just because it's more standard in the Oracle world. And always use VARCHAR2 instead of VARCHAR, which is officially discouraged.

Related

Constraint not working as desired for my INSERT?

I am creating a Table named "Cliente" with some constraints on it as it follows:
CREATE TABLE public."Cliente" (
"K_CODCLIENTE" numeric(5) NOT NULL,
"N_NOMBRE1" varchar(15) NOT NULL,
"N_NOMBRE2" varchar(15) NOT NULL,
"N_APELLIDO1" varchar(15) NOT NULL,
"N_APELLIDO2" varchar(15),
"N_DIRECCION" varchar(50) NOT NULL,
"Q_TELEFONO" numeric(10) NOT NULL,
"K_CODREF" numeric(5),
"I_TIPOID" varchar(2) NOT NULL,
"Q_IDENTIFICACION" varchar(10) NOT NULL,
CONSTRAINT "PK_Cliente" PRIMARY KEY ("K_CODCLIENTE"),
CONSTRAINT "UQ_ID_TIPOID_CLIENTE" UNIQUE ("I_TIPOID","Q_IDENTIFICACION"),
CONSTRAINT "CK_CODCLIENTE" CHECK ("K_CODCLIENTE" >= 100),
CONSTRAINT "CK_Q_IDENTIFICACION" CHECK ("Q_IDENTIFICACION" IN ('CC', 'PA', 'CE', 'NI', 'OT'))
);
When I try to insert some values on it:
INSERT INTO "Cliente"
VALUES ('101','Juan','Felipe','Ortiz','Rojas','AK 15 no. 28-05','3101125507',null,'CC','51111111');
I get the following error (in PostgreSQL 14, on Fedora):
[23514] ERROR: new row for relation "Cliente" violates check constraint "CK_Q_IDENTIFICACION"
Detail: Failing row contains (101, Juan, Felipe, Ortiz, Rojas, AK 15 no. 28-05, 3101125507, null, CC, 51111111).
I am trying to restrict the "Q_IDENTIFICACION" column so it can only be filled with 'CC', 'PA', 'CE, 'NI' or 'OT'.
Maybe I'm doing something wrong when declaring the constraint "CK_Q_IDENTIFICACION"?
Seems like you messed up the mapping of values and are trying to insert '51111111' to "Q_IDENTIFICACION".
Consider this more revealing variant with a formatted list of target columns:
INSERT INTO "Cliente"
("K_CODCLIENTE", "N_NOMBRE1", "N_NOMBRE2", "N_APELLIDO1", "N_APELLIDO2", "N_DIRECCION" , "Q_TELEFONO", "K_CODREF", "I_TIPOID", "Q_IDENTIFICACION")
VALUES ('101' , 'Juan' ,'Felipe' , 'Ortiz' , 'Rojas' , 'AK 15 no. 28-05', '3101125507', NULL , 'CC' , '51111111'); -- !
Maybe you want to switch the last two column names in the table definition - and (not) adapt the VALUES list in the INSERT accordingly? (varchar(2) vs. varchar(10) seems switched as well.)
For persisted code, it's generally advisable to spell out target columns in an INSERT command in any case.
Asides:
Reconsider all these pesky double-quoted upper case identifiers. See:
Are PostgreSQL column names case-sensitive?
Consider plain type text instead of varchar(n) with strikingly tight character limits. See:
Any downsides of using data type "text" for storing strings?

I just want to use time in this colum (novice)

CREATE TABLE Vitals
(
Record_No int NOT NULL PRIMARY KEY,
Patient_ID int,
Date_Taken DATE NOT NULL,
Time_Taken time(7) NOT NULL,
Systolic int,
CHECK (Systolic > Diastolic),
Diastolic int,
Heart_Rate int CHECK (Heart_Rate > 30),
CONSTRAINT fk_Patient_ID FOREIGN KEY (Patient_ID) REFERENCES Patients(Patient_ID)
);
But, I get an error
Time_Taken time(7) NOT NULL,
*
ERROR at line 6:
ORA-00907: missing right parenthesis
When I use timestamp default systimestamp
it works. All I need is the time for Time_Taken column.
enter image description here
You can not use the TIME data type as it is not the oracle defined datatype.
You can use the DATE or TIMESTAMP data type to store time with date.
Supported data types in oracle are documented here.

"Not a valid month" or number

Getting this error while trying to put a few inserts into a table.
Getting an error regarding not a valid month and when I try change it around i'm getting invalid number error.
ORA-01843: not a valid month ORA-06512: at "SYS.DBMS_SQL"
Code:
CREATE TABLE ExpenseReport (
ERNo NUMERIC(10) NOT NULL,
ERDesc VARCHAR(255) NOT NULL,
ERSubmitDate DATE DEFAULT CURRENT_TIMESTAMP,
ERStatusDate DATE NOT NULL,
ERStatus VARCHAR(8) DEFAULT 'PENDING',
SubmitUserNo NUMERIC(10) NOT NULL,
ApprUserNo NUMERIC(10) NOT NULL,
CONSTRAINT ExpenseReport_CK1 CHECK (ERStatusDate >= ERSubmitDate),
CONSTRAINT ExpenseReport_CK2 CHECK (ERStatus = 'PENDING'/'APPROVED'/'DENIED'),
CONSTRAINT ExpenseReport_PK1 PRIMARY KEY(ERNo),
CONSTRAINT ExpenseReport_FK1 FOREIGN KEY(SubmitUserNo) REFERENCES Users(UserNo),
CONSTRAINT ExpenseReport_FK2 FOREIGN KEY(ApprUserNo) REFERENCES (USerNo)
);
INSERT INTO ExpenseReport
(ERNo, ERDesc, ERSubmitDate, ERStatusDate, ERStatus, SubmitUserNo, ApprUSerNo)
VALUES (1,'Sales Presentation','8/10/2002','8/26/2002','APPROVED',3,4);
I've also tried using the TO_DATE but having no luck there,
by any chance can anyone see where i'm going wrong.
Use the DATE keyword and standard date formats:
INSERT INTO ExpenseReport (ERNo, ERDesc, ERSubmitDate, ERStatusDate, ERStatus, SubmitUserNo, ApprUSerNo)
VALUES (1, 'Sales Presentation', DATE '2001-08-10', DATE '2001-08-2006', 'APPROVED', 3, 4);
In addition to the satisfaction of using standard date formats, this protects you against changes in local settings.
In your DDL statement:
CONSTRAINT ExpenseReport_CK2 CHECK (ERStatus = 'PENDING'/'APPROVED'/'DENIED')
Should be:
CONSTRAINT ExpenseReport_CK2 CHECK (ERStatus IN ( 'PENDING', 'APPROVED', 'DENIED' ) )
When you are trying to insert values the check constraint is being evaluated and it is trying to perform a division operation on the three string values'PENDING'/'APPROVED'/'DENIED' which results in ORA-01722: invalid number.
Once you change this then using TO_DATE('01/01/02','DD/MM/YY') (as you wrote in comments) or an ANSI date literal DATE '2002-01-01' should work in your DML statements.
(Note: Be careful using 2-digit years or you can find that dates are inserted with the wrong century.)
Check your date format: select sysdate from dual;
and enter as it show. OR
change your date format: alter session set nls_date_format= 'DD-Mon-YYYY HH24:MI:SS';
It Was Easy :
if Your code Like This just remove hem and write that
Example :
Your code : values ('30178','K111', '22/12/2008')
Do This : values ('30178','K111', '22/Dec/2008')

ORACLE SQL - Count

I have the following schema in Oracle DB:
create table DVD (
dvdID char(25) not null,
datePurchased DATE not null,
filmID char(25) not null,
PRIMARY KEY (dvdID),
FOREIGN KEY (filmID) REFERENCES Film(filmID)
);
create table MonthlyStatement(
customerID char(25) not null,
dvdID char(25) not null,
dateHired DATE not null,
dateReturned DATE,
PRIMARY KEY (dvdID, customerID, dateHired),
FOREIGN KEY (customerID) REFERENCES Customer(customerID),
FOREIGN KEY (dvdID) REFERENCES DVD(dvdID)
);
insert into MonthlyStatement values ('0001','0005','06-oct-2015',null);
insert into MonthlyStatement values ('0001','0006','06-oct-2015','11-oct-2015');
insert into MonthlyStatement values ('0002','0002','02-sep-2015','12-sep-2015');
insert into MonthlyStatement values ('0002','0003','02-sep-2015','12-sep-2015');
insert into MonthlyStatement values ('0003','0018','06-oct-2015','12-oct-2015');
insert into MonthlyStatement values ('0004','0041','02-oct-2015','09-oct-2015');
I have the following description to make a query for:
List all DVDs that were hired in October 2015 (including those that were not returned in October). For each DVD, list its unique number and the number of times it was hired. Sort the DVDs in ascending order of DVD numbers.
How do I solve this?
Try like this
select * from DVD
inner join MonthlyStatement on DVD.dvdID =MonthlyStatement.dvdID
where to_char(MonthlyStatement.dateHired,'Mon-YYYY')='Oct-2015'
order by DVD.dvdID
COUNT
select DVD.dvdID,DVD.datePurchased,DVD.filmID,Count(MonthlyStatement.dateHired) from DVD
inner join MonthlyStatement on DVD.dvdID =MonthlyStatement.dvdID
where to_char(MonthlyStatement.dateHired,'Mon-YYYY')='Oct-2015'
group by DVD.dvdID,DVD.datePurchased,DVD.filmID
order by DVD.dvdID
There are multiple issues.
'06-oct-2015'
Firstly, '06-oct-2015' is not a DATE, it is a string. Both are different. You must always use TO_DATE to explicitly convert a literal into DATE with proper FORMAT MODEL.
TO_DATE is NLS dependent. So, you need to take care of the NLS parameters at individual statement level. You could do it at session too.
TO_DATE('06-oct-2015','dd-mon-yyyy','nls_date_language=american')
When dealing with only date element, i.e. without time element, I prefer the ANSI Date literal which follows a fixed format YYYY-MM-DD and therefore it is NLS independent:
DATE '2015-10-06'
dvdID char(25)
The CHAR datatype stores fixed-length character strings. String values will be space-padded before being stored on disk which is an inefficient way. It is much more efficient to use the VARCHAR2 data type when storing variable-length strings.
List all DVDs that were hired in October 2015 (including those that were not returned in October).
It is a simple join of the two tables, and a filter predicate on the dateHired column:
where to_char(MonthlyStatement.dateHired,'Mon-YYYY','nls_date_language=american')='Oct-2015'
Remember, using TO_CHAR would suppress any regular index on the column. Either use a function-based index or better use a date_range condition for better performance which will use the regular index.

Oracle SQL Query - Age

So I have the following table in my Oracle Database:
create table FilmStar (
filmStarID char(25) not null,
filmStarName char(50) not null,
birthplace char(50) not null,
yearBorn char(25) not null,
yearDied char(25),
primary key (filmStarID)
);
insert into FilmStar values ('0001','Tim Robbins','California, United States','1958',null);
insert into FilmStar values ('0005','Marlon Brando','Nebraska, United States','1924','2004');
I need to complete the following query: List the unique numbers, names, and ages of all film stars who are deceased.
I believe that I need to
select * from FilmStar where yearDied is not null
but how to find out the age?
I prefer to be explicit about type conversions:
select . . .,
(cast(yearDied as int) - cast(yearBorn as int) ) as approximate_age
from FilmStart
where yearDied is not null;
Relying on implicit conversions can result in very hard to find errors. Storing numbers as strings just exacerbates this problem.
Note: in Oracle, one is inclined to use to_number() rather than cast() for this purpose.