date format in oracle custom - sql

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

Related

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 query ORA-01843

I have the following DDL and DML statements :
create table emp_details (
ID number(2) constraint t_pk primary key,
F_Name varchar(10) not null,
L_Name varchar(10) not null,
DOB date,
Mob_no number(10),
City varchar(10),
PIN number(5),
Gender char(1),
Designation varchar(15),
Join_Date date,
);
insert into emp_details values (01,'John','Wick','1990-07-05',9856482358,'Goa',403001,'M','SDE II', '2015-01-08');
then, I get the error of ORA-01843. So, what could be the problem?
The easiest thing to do here is to use ANSI date literals instead of strings for the dates (using strings will depend on the value of NLS_DATE_FORMAT and you don't want to play around with that if you don't have to):
INSERT INTO emp_details
VALUES
( 01, 'John', 'Wick', DATE'1990-07-05', 9856482358
, 'Goa', 403001, 'M', 'SDE II', DATE'2015-01-08');
I have to add that explicitly listing the columns into which you're inserting values is a good habit to have. Otherwise, your INSERT query will break if you or someone else adds a column from your table:
INSERT INTO emp_details
( id, f_name, l_name, dob, mob_no, city, pin, gender, designation, join_date )
VALUES
( 01, 'John', 'Wick', DATE'1990-07-05', 9856482358
, 'Goa', 403001, 'M', 'SDE II', DATE'2015-01-08');
Last, another good practice is to use VARCHAR2 instead of VARCHAR when you're working with Oracle. Currently they work the same, but Oracle "reserves the right" to change VARCHAR to meet with the ANSI standard under which NULL values and the empty string won't be the same (with VARCHAR2 they will always be the same). IOW, the behavior of VARCHAR values in Oracle can change.
It seems when you query with
select * from nls_session_parameters p where p.parameter = 'NLS_DATE_FORMAT';
you won't get YYYY-MM-DD or YYYY-DD-MM from your result of error ORA-01843.
This problem is due to inserting wrong-formatted value for date columns DOB and Join_date.
There may be two ways to prevent this error :
Assume you get DD/MM/YYYY from above query, then use 05-07-1990 for
DOB, and 08/01/2015 for Join_Date columns, respectively.
Format your values as to_date('1990-07-05','YYYY-MM-DD') for
DOB and to_date('2015-01-08','YYYY-MM-DD') for Join_Date

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

ORA-00984 Column not allowed here with date in oracle 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'

I am trying To add Check constraint for checking age and date of birth [duplicate]

This question already has answers here:
CHECK constraint on date of birth?
(5 answers)
Closed 8 years ago.
CREATE TABLE "TEST"."AB_EMPLOYEE22"
( "NAME" VARCHAR2(20 BYTE),
"AGE" NUMBER,
"SALARY" NUMBER,
"DOB" DATE
)
alter table "TEST"."AB_EMPLOYEE22" add constraint
Age_check check((ROUND((sysdate-DOB)/365)) = AGE) ENABLE
But This query is not working.
Pls help me out
Disclaimer: It's not a direct answer to the question.
Now, don't store derived and most importantly constantly changing data such as age in the table. Instead calculate it on the fly when you query it (e.g. with a view).
CREATE TABLE ab_employee22
(
name VARCHAR2(20),
salary NUMBER,
dob DATE
);
CREATE VIEW ab_employee22_view AS
SELECT name, salary, dob,
FLOOR(MONTHS_BETWEEN(sysdate, dob) / 12) age
FROM ab_employee22;
Here is SQLFIddle demo
You cannot use SYSDATE in check constraint. According to Oracle Documentation - Check Constraint
Conditions of check constraints cannot
contain the following constructs:
Subqueries and scalar subquery expressions
Calls to the functions that are not deterministic (CURRENT_DATE,
CURRENT_TIMESTAMP, DBTIMEZONE,
LOCALTIMESTAMP, SESSIONTIMEZONE,
SYSDATE, SYSTIMESTAMP, UID, USER, and
USERENV)
Calls to user-defined functions
Dereferencing of REF columns (for example, using the DEREF function)
Nested table columns or attributes
The pseudocolumns CURRVAL, NEXTVAL, LEVEL, or ROWNUM
Date constants that are not fully specified
So, you can use Trigger to get your desired output in this case. Here, is the trigger which will work fine as per your requirement:
CREATE OR REPLACE TRIGGER trg_check_date
BEFORE INSERT OR UPDATE ON AB_EMPLOYEE22
FOR EACH ROW
BEGIN
IF(ROUND((sysdate-nvl(:NEW.DOB,:OLD.DOB))/365) <> nvl(:NEW.AGE,:OLD.AGE))
THEN
RAISE_APPLICATION_ERROR( -20001, 'Your Date of Birth and Age do not match');
END IF;
END;
If you find any difficulty in this trigger, please feel free to write in comments.
It is not possible to user system variables like 'Sysdate' in a constraint.
Link: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:465820332843
suggestion is to use a trigger with the same logic
Forget about having SYSDATE since its not valid or using a trigger for a workaround. I will show you a cheap trick!!!
Write sysdate into a column and use it for validation. This column might be your audit column (For eg: creation date)
CREATE TABLE "AB_EMPLOYEE22"
(
"NAME" VARCHAR2 ( 20 BYTE ),
"AGE" NUMBER,
"SALARY" NUMBER,
"DOB" DATE,
"DOJ" DATE DEFAULT SYSDATE
);
Table Created
ALTER TABLE "AB_EMPLOYEE22" ADD CONSTRAINT
AGE_CHECK CHECK((ROUND((DOJ-DOB)/365)) = AGE) ENABLE;
Table Altered
You have missed an parameter of round function.
alter table AB_EMPLOYEE22 add constraint
Age_check check((ROUND((sysdate-DOB)/365,0)) = AGE) ENABLE