ORA-00984 Column not allowed here with date in oracle SQL - sql

Im inserting values into this table
CREATE TABLE Flight (
FlightNumber char(7) primary key,
ArrivalAirportCode char(6) references Airport (Airport_code),
DepartureAirportCode char(6) references Airport (Airport_code),
AircraftNumber varchar2(25) references Aircraft (AircraftNumber),
ArrivalDate date,
ArrivalTime Varchar2(5),
DepartureDate date,
DepartureTime varchar2(5)
);
and here are the values Im inserting into it
INSERT INTO FLIGHT values
('CA3048',
'LHR',
'EDI',
'N859E',
'14-NOV-2014',
'22:15',
'14-NOV-2014',
'20:15');
And I get the column not allowed here error for the 2nd date I insert, but not the first one. I've tried putting quotes around the date but I just get another error.

'14-NOV-2014'
Why are you inserting a string in a DATE column? '14-NOV-2014' is a STRING and NOT a DATE. You should not depend on implicit data type conversion.
Always, convert the string into a DATE explicitly using TO_DATE and proper format mask.
For example,
TO_DATE('14-NOV-2014','DD-MON-YYYY')
One more thing,
DepartureTime varchar2(5)
Makes no sense. You already have a DATE column, a DATE would have the time element too.
No need of a separate time column. A DATE has both date and time elements stored in 7 bytes.
Oracle stores DATE in total of 7 bytes. Each byte in it stores values for an element of the DATE as follows:
Byte Description
---- ------------------------------------------------
1 Century value but before storing it add 100 to it
2 Year and 100 is added to it before storing
3 Month
4 Day of the month
5 Hours but add 1 before storing it
6 Minutes but add 1 before storing it
7 Seconds but add 1 before storing it
All you need to do is just have 2 DATE columns:
CREATE TABLE Flight (
FlightNumber char(7) primary key,
ArrivalAirportCode char(6) references Airport (Airport_code),
DepartureAirportCode char(6) references Airport (Airport_code),
AircraftNumber varchar2(25) references Aircraft (AircraftNumber),
ArrivalDate date,
DepartureDate date
);
And then insert the values as:
INSERT INTO FLIGHT values
('CA3048',
'LHR',
'EDI',
'N859E',
TO_DATE('14-NOV-2014 22:15:00','DD-MON-YYYY HH24:MI:SS'),
TO_DATE('14-NOV-2014 20:15:00','DD-MON-YYYY HH24:MI:SS')
);
Update
As mentioned in the comments by #GriffeyDog and #a_horse_with_no_name.
Alternatively, you could also the ANSI literal instead, for example:
timestamp '2014-11-14 22:15'

Related

Subtract two timestamptz values and insert the result into a third column

I have the following table:
CREATE TABLE duration
(
departure_time TIMESTAMPTZ,
arrival_time TIMESTAMPTZ,
duration TIME NOT NULL, -- Not sure about the datatype..
flight_id INT UNIQUE NOT NULL,
CHECK (scheduled_duration > 0),
CHECK (scheduled_arrival_time > scheduled_departure_time),
FOREIGN KEY (flight_id) REFERENCES flight(flight_id),
PRIMARY KEY (scheduled_departure_time, scheduled_arrival_time)
);
I want to calculate arrival_time - departure_time and then insert the result into the column duration. Preferably, the result of the duration subtraction would be 6h 30m. I am new to databases and PostgreSQL and I can't find a way to calculate a subtraction of two timestamps, taking into consideration their timezones at the same time.
Use a generated column
CREATE TABLE duration
(
departure_time TIME WITH TIME ZONE,
arrival_time TIME WITH TIME ZONE,
scheduled_duration INT,
flight_id INT,
duration2 TIME GENERATED ALWAYS AS ("arrival_time"::time - "departure_time"::time) STORED,
CHECK (scheduled_duration > 0),
CHECK (arrival_time > departure_time),
FOREIGN KEY (flight_id) REFERENCES flight(flight_id),
PRIMARY KEY (departure_time, arrival_time)
);
SELECT
EXTRACT(EPOCH FROM '2022-07-07 15:00:00.00000'::TIMESTAMP - '2022-07-07 15:00:00.00000'::TIMESTAMP)

date format in oracle custom

I want to create a table Emp with the dob in the format ddmmyy but I'm not sure how to do it, this is what I've come up with so far
Emp(eno,name,dob);
create table Emp(
eno number constraint c1 as primary key
, name varchar2(50)
, dob date
);
In Oracle, a DATE is a binary data-type consisting of 7-bytes representing: century, year-of-century, month, day, hour, minute and second. It ALWAYS has those 7 components and it NEVER stores any particular (human-readable) format.
I want to create a table Emp with the dob in the format ddmmyy
You cannot as a DATE never stores any format.
What you can do is enforce that the time component will always be midnight and, if you wanted the formatting to be managed in the table, you could add a virtual column:
CREATE TABLE Emp(
eno NUMBER(10,0)
GENERATED ALWAYS AS IDENTITY
CONSTRAINT emp__eno__pk PRIMARY KEY,
name VARCHAR2(50),
dob DATE
CONSTRAINT emp__dob__chk CHECK (dob = TRUNC(dob)),
formatted_dob VARCHAR2(6)
GENERATED ALWAYS AS (TO_CHAR(dob, 'DDMMYY'))
);
Then you can:
INSERT INTO emp (name, dob) VALUES ('Alice', TRUNC(SYSDATE));
and the table contains:
ENO
NAME
DOB
FORMATTED_DOB
1
Alice
2022-04-26T00:00:00
260422
Note: the dob column is formatted according to the the configuration of the client application you are using to access the database. In the example above, it is set to use an ISO8601 format.
However, it is more usual to treat the formatting of a DATE as a display issue and then you do not need a virtual column and can set whatever format you require in the SQL statement (or in the 3rd party application used to access the database). For example, in SQL you could use:
SELECT eno,
name,
TO_CHAR(dob, 'DDMMYY') AS dob
FROM emp;
db<>fiddle here

ORA-01858 FOR BEGINNER

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.

how to create date

how to create date format yyyy-mm with postgresql11
CREATE TABLE public."ASSOL"
(
id integer NOT NULL,
"ind" character(50) ,
"s_R" character(50) ,
"R" character(50) ,
"th" character(50),
"C_O" character(50) ,
"ASSOL" numeric(11,3),
date date,
CONSTRAINT "ASSOL_pkey" PRIMARY KEY (id)
This is a variation of Kaushik's answer.
You should just use the date data type. There is no need to create another type for this. However, I would implement this use a check constraint:
CREATE TABLE public.ASSOL (
id serial primary key,
ind varchar(50) ,
s_R varchar(50) ,
R varchar(50) ,
th varchar(50),
C_O varchar(50) ,
ASSOL numeric(11,3),
yyyymm date,
constraint chk_assol_date check (date = date_trunc('month', date))
);
This only allows you to insert values that are the first day of the month. Other inserts will fail.
Additional notes:
Don't use double quotes when creating tables. You then have to refer to the columns/tables using double quotes, which just clutters queries. Your identifiers should be case-insensitive.
An integer primary key would normally be a serial column.
NOT NULL is redundant for a PRIMARY KEY column.
Use reasonable names for columns. If you want a column to represent a month, then yyyymm is more informative than date.
Postgres stores varchar() and char() in the same way, but for most databases, varchar() is preferred because trailing spaces actually occupy bytes on the data pages.
for year and month you can try like below
SELECT to_char(now(),'YYYY-MM') as year_month
year_month
2019-05
You cannot create a date datatype that stores only the year and month component. There's no such option available at the data type level.
If you want to to truncate the day component to default it to start of month, you may do it. This is as good as having only the month and year component as all the dates will have day = 1 and only the month and year would change as per the time of running insert.
For Eg:
create table t ( id int, col1 text,
"date" date default date_trunc('month',current_date) );
insert into t(id,col1) values ( 1, 'TEXT1');
select * from t
d col1 date
1 TEXT1 2019-05-01
If you do not want to store a default date, simply use the date_trunc('month,date) expression wherever needed, it could either be in group by or in a select query.

SQL: how to specify a date format on creating a table and fill it

I want to save the date in format 'dd.mm.yyyy'. So I read there are different formats for a date in SQL (by the way I use Visual Studio and SQL Server).
I tried this code:
CREATE TABLE APP(
ID INT NOT NULL,
DT DATE FORMAT 'dd.mm.yyyy',
ADDRESS NVARCHAR (100) ,
PRIMARY KEY (ID)
);
But it returns the error:
Incorrect syntax near 'FORMAT'.
After that I want to use this code:
INSERT INTO APP (ID, DT)
VALUES ('1','22.12.2016')
You don't need to specify the format in the table definition as dates are stored in a binary format.
CREATE TABLE APP(
ID INT NOT NULL,
DT DATE,
ADDRESS NVARCHAR (100) ,
PRIMARY KEY (ID)
);
When you try to insert into that table however, the server will try to convert the string to a date before inserting it. This can be problematic as it is unable to tell if 12.11.2017 is the 12th of November or 11th of December. To figure this out it uses the localization settings of the user account that is performing the operation.
Often you will find that the account that is running the operation is set to USA format, month day then year (MDY), when what you want is day month year (DMY) format. One way to tell it what the sequence of the date's parts is to use the DATEFORMAT setting like this:
SET DATEFORMAT dmy;
INSERT INTO APP (ID, DT)
VALUES (1,'22.12.2016')
Another alternative is to cast the string to a date using the CONVERT function and tell it what the date format is. The formats have numeric codes like 104 for German format Like this:
INSERT INTO APP (ID, DT)
VALUES (2,CONVERT(date,'22.12.2016',104))
Dates are stored in an internal format. Formats only make sense for input and output.
In your case you want the date in a German format (104), so you can use:
select convert(varchar(255), dt, 104)
If you like, you can include the formatted date as a separate column:
CREATE TABLE APP (
ID INT NOT NULL,
DT DATE,
ADDRESS NVARCHAR(100),
DT_FORMATTED AS (convert(varchar(255), dt, 104)),
PRIMARY KEY (ID)
);
You can then refer to dt_formatted to get the string in the format you want.
Use this:
CREATE TABLE APP(
ID INT NOT NULL,
DT DATE ,
ADDRESS NVARCHAR (100) ,
PRIMARY KEY (ID)
);
Its default setting is yyyy-MM-dd.
No, it's not. There is no formatting information at all associated with the field.
The value is not formatted by the database. It's returned only as a point in time. Formatting that value into its textual representation is done by the application that is getting the data from the database.
So, there is nothing that you can do in the database to change how the date value is formatted. You have to change that where the data is displayed.
Dates are stored in an internal format.
Formats only make sense for input and output.
You can include the formatted date as a separate column:
SQL Server supports the date format. You have to use the below date format.
With century (yyyy) | Standard | Input/Output
103 | British/French | 103 = dd/mm/yyyy
CREATE TABLE [dbo].[Post]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] VARCHAR(MAX) NULL,
[RowNo] INT NULL,
[ColNo] INT NULL,
[Deadline] (CONVERT(VARCHAR(255), dt, 103)), -- Include the formatted date as a separate column
CONSTRAINT [PK_KtoCo]
PRIMARY KEY CLUSTERED ([Id] ASC)
);
Use this.
CREATE TABLE:
CREATE TABLE EMP
(EID NUMBER(20),
ENAME VARCHAR2(20),
DT DATE,
SAL NUMBER(20));
INSERT INTO THE TABLE:
INSERT INTO EMP (EID,ENAME,DT,SAL) VALUES(01,'ABCDE','11.NOV.2011',10000);
O/P OF ABOVE TABLE:
SELECT * FROM EMP;
EID ENAME DT SAL
01 ABCDE 11-DEC-11 10000