Auto generate primary key as current date time in H2 database - sql

I have to create a table in H2 with primary key in yyyyMMddHHmmssSSS format.So that for every insert it automatically takes current date time in the mentioned format.
CREATE TABLE TEST_TABLE(ID BIGINT DEFAULT CURRENT_TIMESTAMP() PRIMARY KEY, NAME VARCHAR(255));
Problem is CURRENT_TIMESTAMP() format is yyyy-MM-dd HH:mm:ss.SSS.How can I get it in required format.

You can try this in the H2 console:
call formatdatetime(now(),'yyyyMMddHHmmssSSS');
This will give you a properly formatted string. Now you need to convert it to bigint.
call cast(formatdatetime(now(),'yyyyMMddHHmmssSSS') as bigint);
Last step: change your SQL accordingly...
CREATE TABLE TEST_TABLE(
ID BIGINT DEFAULT CAST(FORMATDATETIME(CURRENT_TIMESTAMP(), 'yyyyMMddHHmmssSSS') AS BIGINT) PRIMARY KEY,
NAME VARCHAR(255)
);
Tested on H2 1.3 and 1.4.
Word of caution: please use transactions and space your insertions...

Related

H2 refuses to create auto_increment for Postgres emulated database

I created an in memory H2 database with JDBC URL
jdbc:h2:~/test;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH
The H2 web console refuses to let me do an auto_increment. I've seen serial for Postgres, but that doesn't work either.
At it's simplest, it hates:
create table test(id bigint auto_increment);
Syntax error in SQL statement "create table test(id bigint [*]auto_increment)"; expected "ARRAY, INVISIBLE, VISIBLE, NOT NULL, NULL, AS, DEFAULT, GENERATED, ON UPDATE, NOT NULL, NULL, DEFAULT ON NULL, NULL_TO_DEFAULT, SEQUENCE, SELECTIVITY, COMMENT, CONSTRAINT, COMMENT, PRIMARY KEY, UNIQUE, NOT NULL, NULL, CHECK, REFERENCES, ,, )"; SQL statement:
create table test(id bigint auto_increment) [42001-214] 42001/42001 (Help)
Why do I care:
My code base was failing with NULL not allowed for column "REV". I'm using JPA/Hibernate + Liquibase. In order to try the suggestions at
Hibernate Envers + Liquibase: NULL not allowed for column "REV"
I'm trying to add an auto_increment to my Liquibase changelog file.
You can use the SQL Standard's generation clause GENERATED ALWAYS AS IDENTITY. For example:
create table test (
id bigint generated always as identity,
name varchar(10)
);
See PostgreSQL Example.
It works the same way in H2. For example:
create table test(id bigint generated always as identity, name varchar(10));
insert into test (name) values ('Chicago') ;
select * from test;
Result:
ID NAME
-- -------
1 Chicago

Why is the column not altering when I try to convert it to UUID?

I have a primary key column in my SQL table in PostgreSQL named "id". It is a "bigseries" column. I want to convert the column to a "UUID" column. It entered the below command in the terminal:
alter table people alter column id uuid;
and
alter table people alter column id uuid using (uuid_generate_v4());
but neither of them worked.
In both tries I got the error message
ERROR: syntax error at or near "uuid"
LINE 1: alter table people alter column id uuid using (uuid_generate...
What is the correct syntax?
First of all uuid_generate_v4() is a function which is provided by an extension called uuid-ossp. You should have install that extension by using;
CREATE EXTENSION uuid-ossp;
Postgresql 13 introduced a new function which does basically the same without installing extension. The function is called gen_random_uuid()
Suppose that we have a table like the one below;
CREATE TABLE people (
id bigserial primary key,
data text
);
The bigserial is not a real type. It's a macro which basically creates bigint column with default value and a sequence. The default value is next value of that sequence.
For your use case, to change data type, you first should drop the old default value. Then, alter the type and finally add new default value expression. Here is the sample:
ALTER TABLE people
ALTER id DROP DEFAULT,
ALTER id TYPE uuid using (gen_random_uuid() /* or uuid_generate_v4() */ ),
ALTER id SET DEFAULT gen_random_uuid() /* or uuid_generate_v4() */ ;
CREATE TABLE IF NOT EXISTS people (
id uuid NOT NULL CONSTRAINT people_pkey PRIMARY KEY,
address varchar,
city varchar(255),
country varchar(255),
email varchar(255),
phone varchar(255)
);
This is the correct syntax to create table in postgres SQL, it's better to do these constraints at beginning to avoid any error.
For using alter command you would do the following:
ALTER TABLE customer ADD COLUMN cid uuid PRIMARY KEY;
Most of errors that you could find while writing command either lower case or undefined correct the table name or column.

Can't use "GENERATED ALWAYS AS IDENTITY" when creating Postgres tables on Dbeaver?

I am using Dbeaver to create a Postgres database table but am getting a syntax error when using "GENERATED ALWAYS AS IDENTITY" for my incremented id value. It is strange because I used the exact same syntax when creating the table on my localhost and had no problem with any syntax errors or creating the table.
This is the SQL preview I have when attempting to save the table:
CREATE TABLE public.conversation (
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY,
startdatetime timestamptz NOT NULL,
enddatetime timestamptz NOT NULL,
CONSTRAINT conversation_pk PRIMARY KEY (id)
);
When I try to save the table, I get "ERROR: syntax error at or near 'GENERATED'". I thought this was correct syntax considering the SQL is built by Dbeaver itself and it worked fine when creating a local database to test on?
Just use bigserial:
CREATE TABLE public.conversation (
id bigserial primary key,
startdatetime timestamptz NOT NULL,
enddatetime timestamptz NOT NULL
);

Liquibase ignorable comments

Is there a way we can add comments in liquibase file which are not parsed by the program?
We are using the text format for the changes.sql and this is how it looks
--changeset Sapan.Parikh:MyUniqueAlphaNumericId5
--comment: Table created for liquibase testing purpose with non numeric id
--6:10 PM 11/10/2015
create table liqui_test11 (
id int primary key,
name varchar(255)
);
create table liqui_test9 (
id int primary key,
name varchar(255)
);
create table liqui_test10 (
id int primary key,
name varchar(255)
);
Our organization has been using similar change log for years and while migrating to Liquibase we want to be able to do two things.
Add dashes or hashes after each changeset.
And after every production build we add a comment at the end of the changes file.
For instance
--changeset Sapan.Parikh:MyUniqueAlphaNumericId5
--comment: Table created for liquibase testing purpose with non numeric id
--6:10 PM 11/10/2015
create table liqui_test11 (
id int primary key,
name varchar(255)
);
-----------------------------------------------------------------
--changeset Sapan.Parikh:MyUniqueAlphaNumericId4
--comment: Table created for liquibase testing purpose with non numeric id
--6:10 PM 11/10/2015
create table liqui_test12 (
id int primary key,
name varchar(255)
);
###------------------Build 10.0.1 Made-------------------
Now if we add just dashes- or # the luqibase task is breaking and DB upgrade does not happen. Is there a way to accommodate comments which are not parsed by liquibase engine?
You can just persist your comments and strip them right before executing liquibase
- can be done easily using sed

How do I create an updated "date" field using SQLITE 3?

I am writing a program to help me keep track of my day to day life, and I want one of the fields to be a "date" field that will automatically update. What specifically do I do in SQLITE 3? Something like....
create table day_to_day(
date field
miles_ran INTEGER
food_eaten TEXT
)
How about:
CREATE TABLE day_to_day(
id INTEGER PRIMARY KEY AUTOINCREMENT,
t TIMESTAMP DEFAULT CURRENT_TIMESTAMP
miles_ran INTEGER
food_eaten TEXT
);
which would give you a column called t with the type TIMESTAMP, as a alternative you could also use this:
CREATE TABLE day_to_day(
id INTEGER PRIMARY KEY AUTOINCREMENT,
t DATE DEFAULT (datetime('now','localtime')),
miles_ran INTEGER
food_eaten TEXT
);
Maybe you can use this :
CREATE TABLE table_test (
...
date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
or
CREATE TABLE table_test (
...
date DATE DEFAULT (datetime('now','localtime')),
);
This is a good reference : sqlite database default time value 'now'
You can read what the docs have to say about it: SQLite datatypes, scroll to section 1.2.
The gist of it is, you can either use TEXT, REAL, or INTEGER, and then use the corresponding Date/Time function to access it.