I have the employee table:
CREATE TABLE employee
(
id integer PRIMARY KEY,
surname character(15),
employed_date date
);
to which I insert the following row:
INSERT INTO employee
VALUES (4, 'Smith', to_date('2015-11-28','YYYY-MM-DD'));
Can I instead simply write?
INSERT INTO employee
VALUES (4, 'Smith', '2015-11-28');
It works in my PostgreSQL installation. However, I would like to write portable code that works also in other databases, including Oracle, SQL Server, MySQL and SQLite; and with any locales.
Does it work also in these databases? If no, then maybe another format works in these databases and/or is ANSI standard?
Most DBMSes (but not SQL Server & SQLite) support ANSI/Standard SQL date literals with a fixed YYYY-MM-DD format:
date '2020-09-20'
Similar for time and timestamp:
time '12:34:56'
timestamp '2020-09-20 12:34:56.02'
First, you are using a char() type for the surname. This type pads the name with spaces, which is generally unadvisable for names. In general, you want a varchar() for names:
CREATE TABLE employee (
id integer PRIMARY KEY,
surname varchar(15),
employed_date date
);
I should add that 15 characters is probably not long enough for last names.
Or perhaps nvarchar(). The above works in all your mentioned databases, although Oracle recommends varchar2().
As for date constants, there are basically two ways to insert them:
date '2020-11-03'
'2020-11-03'
The first is standard SQL, but not all databases support it. Of the databases you mention, only Oracle requires the date keyword. SQL Server and SQLite don't allow it.
The databases that do not allow date will convert the string to a date, if a date is expected.
So, there is no single way to pass in a date constant that works across the databases you have mentioned. Well, the major exception is Oracle. And you can change the default date format to accept YYYY-MM-DD rather than DD-MMM-RR, but that is rarely done.
You can use the sql statement below to add a new employee to employee table. With the date format 'YYYY-MM-DD'.
INSERT INTO employee (id,name,date) VALUES (4, 'Smith', '2015-11-28')
Related
I have a SQLite database with a simple table in the format of:
ID,DateText,Name
1,2020-09-01T18:57:17Z,John
2,2022-12-01T04:00:09Z,Laurel
...
The DateText column is declared as TEXT on the "create table" statement. Using only SQL, I need to:
Create a new column with the DateText data.
Obtain the "oldest" date
Obtain the "newest" date
Note that I need to resolve this with a SQL query. I cannot read into a programming language, parse, and update table--I need to do everything on SQL. For example, SQL Server DateTime with timezone is the opposite, but they are using node.js, something I cannot do.
You can get the oldest and newest using min() and max():
SELECT ID, min(DateTime), Name FROM YourTable; -- Oldest
SELECT ID, max(DateTime), Name FROM YourTable; -- Newest
The nice thing about ISO-8601 date and time format strings is that they sort lexicographically without having to do anything special with them.
These queries would give an error on most SQL database engines because of the mix of non-grouped columns with an aggregate function, but SQLite explicitly will return the row that goes with the minimum or maximum column value. And of course if you don't want the other columns, just leave them out of the SELECT.
I'm looking to find a way to add a day to a date in both Postgres and SQL Server so I don't have to add an if condition checking which database the server is running
DATEADD(day, 1, STOP_DATE)
doesn't work in PostgreSQL &
STOP_DATE + 1
doesnt work in sql server
Overall, it is not a good idea to try to write SQL code using syntax that is common on both SQL Server and Postgres. You are severely limiting yourself and will sooner or later come across a query that runs too slowly because it doesn't use syntax specific to one of the DBMS.
For example, with your approach you are artificially refusing to use lateral joins, because their syntax is different in Postgres (LATERAL JOIN) and SQL Server (CROSS/OUTER APPLY).
Back to your question.
You can add an integer value to a date value in Postgres and to datetime value in SQL Server.
SQL Server
CREATE TABLE T(d datetime);
INSERT INTO T VALUES ('2020-01-01');
SELECT
d, d+1 AS NextDay
FROM T
http://sqlfiddle.com/#!18/d519d9/1
This will not work with date or datetime2 data types in SQL Server, only datetime.
Postgres
CREATE TABLE T(d date);
INSERT INTO T VALUES ('2020-01-01');
SELECT
d, d+1 AS NextDay
FROM T
http://sqlfiddle.com/#!17/b9670/2
I don't know if it will work with other data types.
Define a function in PostgreSQL that works like the sql server function.
Edit:
can't pass day
Create a function with the same name on each database system that adds a day accordingly.
From what I have seen so far, when inserting into a table that has date value such as "27-10-2004", the following format DD-MON-YYYY is used
insert into tableName values('27-Oct-2004')
Is it possible to insert the date in its original format '27-10-2004' into the table? In general how many variations of this date may be considered correct for inserting into tables (this is without using any built-in functions, just SQL)?
Use a date literal in Oracle:
insert into tableName
values (DATE '2004-10-27');
This defines a date constant using the ISO standard format YYYY-MM-DD.
If you wanted to use a specific format -- which I wouldn't recommend -- then you can convert to a date using to_date():
insert into tableName
values (to_date('27-10-2004', 'DD-MM-YYYY'));
Any particular string that you use is interpreted based on system settings, so it can vary by language and geography.
Note: When inserting a value, you should include the column names. I assume that your code is just for illustrative purposes.
I have created an Azure SQL Server with SQL Database, as well as a table in that database named table1 with columns ID, FirstName, LastName, and DOB. However, when I try to use this statement:
INSERT INTO table1(ID, FirstName, LastName, DOB)
VALUES (1, "Rohit", "Karthik", "8/2/06")
it outputs an error:
Failed to execute query. Error: Invalid column name 'Rohit'.
Invalid column name 'Karthik'.
Invalid column name '8/2/06'.
(BTW: ID is of type int, and all the others are of type varchar)
Shouldn't the above SQL query in SQL Server insert the new row in that table?
I am not sure why this error is coming, please help.
Use single quotes for literal strings. In standard SQL, double quotes stand for column names - hence the error that you are getting:
INSERT INTO table1(ID, FirstName, LastName, DOB)
VALUES (1, 'Rohit', 'Karthik', '8/2/06')
Also, assuming that DOB is of a date-like datatype, you should consider using a more standard format (such as YYYY-MM-DD, or YYYYMMDD) instead of relying on your server's ability to infer the format (although SQL Server is really good at it).
I want to insert a time data in a table . So, what type of datatypes, I should use and how can I insert a time in a table? I used 'timestamp' in create table statement, but when I insert a time in table, it shows an error (error-code : ORA-01861). Please help me. I use ORACLE 11g.
DDL statement:
CREATE TABLE "SOM"."FLIGHTS"
( "FLNO" NUMBER(3,0) NOT NULL ENABLE,
"FROM" VARCHAR2(20 BYTE),
"TO" VARCHAR2(20 BYTE),
"DISTANCE" NUMBER(5,3),
"DEPARTS" TIMESTAMP (3),
"ARRIVES" TIMESTAMP (3),
"PRICE" NUMBER(5,2),
CONSTRAINT "FLIGHTS_PK" PRIMARY KEY ("FLNO") );
insert statement:
insert into flights
values (1, 'Bbsr', 'Calcutta', 600, timestamp '05:30', timestamp '06:50', 8000);
The message for ORA-01861 is literal does not match format string. This error means we're casting a string to another data type but the string has the wrong format.
Your insert statement features two casts of a string to a TIMESTAMP datatype using the ANSI SQL style timestamp() function. This function takes prescribed formats: YYYY-MM-DD HH24.MI.SS, YYYY-MM-DD HH24.MI.SS.FF and YYYY-MM-DD HH24.MI.SS.FF TZ.
You are getting ORA-01861 because your string does not match one of those formats: timestamp '05:30'.
In this case the solution is to change the column datatype: you do not want a timestamp, which is a specific time on a specific date. What you want is just the flight's take-off and landing times, which would be better expressed as number(4,2) or varchar2(5) which a check constraint.
Two other observations.
Your insert statement has numeric value which are too big for the specified number columns, which is easy to fix.
Your table definition uses oracle reserved words as column names, TO and FROM. The create statement succeeds only because you have wrapped everything in double quotes, so Oracle doesn't validate the names. Using reserved words like this is incredibly bad practice. Every time we refer to the columns we will need to write ...
select flno, "FROM", "TO" from flights;
... otherwise the we'll get ORA-00936 (SQLFiddle demo). The poor saps who have to use your table and maintain your code will curse you forever. Don't be that guy.