How to do same thing on multiple conflicts in PostgreSQL? - sql

For example if I have a table:
create table test(
username varchar(50) PRIMARY KEY,
customer varchar(12),
nickname varchar(12)
);
create unique index unique_customer_nickname on test(customer,nickname);
Therefore username is unique and (customer,nickname) together are unique.
Then If I want to write an upsert statement like this:
Insert into test(username,customer,nickname) values('utest','ctest','ntest')
on conflict(username) or on conflict(customer,nickname) DO UPDATE ....
but this gives me syntax error.
I also tried on (conflict(username) or conflict(customer,nickname))
but this also returns a syntax error.
so what I want is for different conflicts to perform the same thing.

Related

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.

SSIS Unique column?

Hello and sorry for newbie question.
I have a very simple SSIS project that imports customer names from file. It all works now fine, however there are multiple entries of same name and I dont want duplicates.
This works just fine, however it populates duplicates:
CREATE TABLE [SLSales].[dbo].[Customer] (
id BIGINT IDENTITY NOT NULL PRIMARY KEY,
name NVARCHAR(100) NOT NULL
);
However, when I try to use this:
CREATE TABLE [SLSales].[dbo].[Customer] (
id BIGINT IDENTITY NOT NULL PRIMARY KEY,
name NVARCHAR(100) NOT NULL UNIQUE
);
All records fail and I get a mysterious -1071607685 error code.
The SSIS way is to:
Load the data from Source
GROUP BY [name] in your case because you can have same name in file
Run through a Lookup (Match and NoMatch outputs)
Insert No Match
Update matches (or in your case you might want to just ignore)

SQLite - NOT NULL constraint failed

I am trying to create a simple SQLite database that will allow me to store email addresses and timestamps. I have created the table like this:
$sql =<<<EOF
CREATE TABLE ENTRIES
(ID INT PRIMARY KEY NOT NULL,
EMAIL EMAIL NOT NULL,
TIMESTAMP DATETIME DEFAULT CURRENT_TIMESTAMP);
EOF;
And I am trying to insert an email like this:
$sql =<<<EOF
INSERT INTO ENTRIES (EMAIL)
VALUES (test#test.com);
EOF;
I am getting an error
NOT NULL constraint failed: ENTRIES.ID
I am assuming this is to do with the ID and autoincrement? I have read the docs and it advises against using autoincrement. Where am I going wrong?
The docs say:
If a table contains a column of type INTEGER PRIMARY KEY, then that column becomes an alias for the ROWID.
And because it becomes an alias for the ROWID, it's not necessary to explicitly specify a value.
You have INT PRIMARY KEY, not INTEGER PRIMARY KEY. If you change it to INTEGER PRIMARY KEY, it works the way you expect.

Why does the zipcode fail the check constraint?

I feel like I am probably missing something really simple, but I really can't figure out what I'm doing wrong. I'm trying to use a check constraint to make sure zipcodes are 5 digit numbers, but the check restraint keeps failing. Here is the table creating with the constraint:
Create Table Students (
StudentID Int Primary Key Identity(1,1)
StudentNumber nVarchar(100) Unique Not Null,
...
StudentZipCode nChar(10) Not Null
)
Go
Alter Table Students Add Constraint chZipCode
CHECK (StudentZipCode LIKE '[0-9][0-9][0-9][0-9][0-9]' OR StudentZipCode
Like '[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
Go
Codes like 12345-6789 work, but when I try to insert the values like '12345' or '01234' it gives me this error:
The INSERT statement conflicted with the CHECK constraint "chZipCode". The conflict occurred in database ..., table "dbo.Students", column 'StudentZipCode'.
It fails because you defined the zip code as a char() instead of a varchar(). Hence, it has a bunch of spaces padding it out.
So, define it as:
Create Table Students (
StudentID Int Primary Key Identity(1,1),
StudentNumber nVarchar(100) Unique Not Null,
StudentZipCode nVarChar(10) Not Null,
CHECK (StudentZipCode LIKE '[0-9][0-9][0-9][0-9][0-9]' OR
StudentZipCode LIKE '[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
);
Then '12345' works, because it matches the first of the LIKE patterns.
'012344' does not work, because no pattern has six digits in a row.
Here is a SQL Fiddle.

How can I execute an `INSERT INTO` on a table with a string primary key?

I have two tables that are initialized with something like this:
create table foo (
"id" varchar(254) not null primary key,
"first_name" varchar(254) not null);
create table my_user (
"id" serial not null primary key,
"role" varchar(254) not null,
"first_name" varchar(254) not null);
The reason why the id column of foo is a varchar(254) instead of a serial is because in normal operations I'm inserting in an id provided by Google OAuth2 instead of generating my own id values.
I now have a set of records in a third table I call temp with the first_name column. I'm trying to emulate this post, but I'm not sure how to do so for string primary keys.
select * from (insert into my_user(id, role)
('some id value I want to generate, like historical || incrementing number',
[a fixed number],
select first_name from temp) returning id);
As it says in the official Postgres documentation, I know I need to get the arguments following the insert statement into the format of a table that matches the declaration of my_user. I guess I'm just lost as to how to generate a column of the ids I want here, or even a column of one number repeating.
Thanks for reading
You could insert a UUID (it's like a GUID) in your ID... It's guaranteed to be unique.
Sadly it's a little complex to load the module: Generating a UUID in Postgres for Insert statement?
Ah... and what wildplasser said, +1! :-)