Can anyone tell me why the following SQL refuses to insert more than 1 result (using sqlite3)? And how to make it insert all distinct values from the select port_shipment?
The cargo table in this database contains more than 2000 distinct values for port_shipment, but I tried several versions of the insert-command which resulted always in only 1 value inserted.
create table port (
port_ID integer not null primary key,
port_description text unique collate nocase,
port_name text,
country text,
lat text,
lon text
)
insert or ignore into port (port_ID, port_description)
values (null, (SELECT port_shipment FROM cargo))
Thanks!
The values statement is not needed with select. Try this:
insert or ignore into port (port_ID, port_description)
SELECT NULL, port_shipment
FROM cargo
Related
I'm running the following SQLite workaround to add a primary key to a table that did not have one. I am getting a datatype mismatch on
INSERT INTO cities
SELECT id, name FROM old_cities;
However, the fields have exactly the same type. Is it possible that his happens due to running the queries from DbBrowser for SQLite?
CREATE table cities (
id INTEGER NOT NULL,
name TEXT NOT NULL
);
INSERT INTO cities (id, name)
VALUES ('pan', 'doul');
END TRANSACTION;
PRAGMA foreign_keys=off;
BEGIN TRANSACTION;
ALTER TABLE cities RENAME TO old_cities;
--CREATE TABLE cities (
-- id INTEGER NOT NULL PRIMARY KEY,
-- name TEXT NOT NULL
--);
CREATE TABLE cities (
id INTEGER NOT NULL,
name TEXT NOT NULL,
PRIMARY KEY (id)
);
SELECT * FROM old_cities;
INSERT INTO cities
SELECT id, name FROM old_cities;
DROP TABLE old_cities;
COMMIT;
You have defined the column id of the table cities to be INTEGER, but with this:
INSERT INTO cities (id, name) VALUES ('pan', 'doul');
you insert the string 'pan' as id.
SQLite does not do any type checking in this case and allows it.
Did you mean to insert 2 rows each having the names 'pan' and 'doul'?
If so, you should do something like:
INSERT INTO cities (id, name) VALUES (1, 'pan'), (2, 'doul');
Later you rename the table cities to old_cities and you recreate cities but you do something different: you define id as INTEGER and PRIMARY KEY.
This definition is the only one that forces type checking in SQLite.
So, when you try to insert the rows from old_cities to cities you get an error because 'pan' is not allowed in the column id as it is defined now.
I have two table with one to one relation and I want to insert two rows to the tables with the same auto increment id. Is it possible?
create table first
(
id bigint primary key,
value varchar(100) not null
);
create table second
(
id bigint references first (id),
sign boolean
);
insert into first(id, value)
values (-- autoincremented, 'some_value');
insert into second(id, sign)
values (-- the same autoincremented, true);
Your id column must be defined as an "auto increment" one before you can use that:
create table first
(
id bigint generated always as identity primary key,
value varchar(100) not null
);
Then you can use lastval() to get the last generated id:
insert into first(id, value)
values (default, 'some_value');
insert into second(id, sign)
values (lastval(), true);
Or if you want to be explicit:
insert into first(id, value)
values (default, 'some_value');
insert into second(id, sign)
values (currval(pg_get_serial_sequence('first','id')), true);
One option uses a cte with the returning clause:
with i as (
insert into first(value) values('some_value')
returning id
)
insert into second(id, sign)
select i.id, true from i
This performs the two inserts at once; the id of the first insert is auto-generated, and then used in the second insert.
For this to work, you need the id of the first table to be defined as serial.
The upsert works using on conflict but the datatype of id is serial meaning I want to have it auto-generated/incremented. If I do the insert without specifying id the insert works fine.
The problem I have is combining the two. To get the key auto incremented I do not pass the id into the insert but if I do not pass id then the update will never fire. I cannot pass null to id as it is non-null field.
In below example - I run the query first time and it does insert and second time it does update but I cannot figure out how to pass 'nothing' to insert so the identity key still works on insert. I can put DEFAULT in the insert but then I cannot pass a real id value if there is one.
CREATE TABLE public.upsert_test
(
id INTEGER NOT NULL DEFAULT nextval('upsert_test_id_seq'::regclass),
name character varying(20) COLLATE pg_catalog."default",
description character varying(20) COLLATE pg_catalog."default",
CONSTRAINT upsert_test_pkey PRIMARY KEY (id)
)
INSERT INTO upsert_test (id, name, description)
VALUES (1, 'thing1', 'test')
on conflict (id)
do update set (name , description) = ('thing_updated','test-updated')
where upsert_test.id = 1;
You can change your query to use sequence functions like:
INSERT INTO upsert_test (id, name, description)
VALUES ((select nextval('upsert_test_id_seq')), 'thing1', 'test')
on conflict (id)
do update set (name , description) = ('thing_updated','test-updated')
where upsert_test.id = (select currval('upsert_test_id_seq'));
Note this may not be threadsafe, for eg if second call to this sql is executed before select currval('upsert_test_id_seq') in first call, then the update may fail in first query.
Update after more information from op
You can change the query to like this:
INSERT INTO upsert_test (id, name, description)
VALUES (COALESCE(:YOUR_ID_PARAM, (select nextval('upsert_test_id_seq'))), 'thing1', 'test')
on conflict (id)
do update set (name , description) = ('thing_updated','test-updated')
where upsert_test.id = :YOUR_ID_PARAM;
Note I added the coalesce function so if your parameter is null then use sequence nextval. Also, the update now also uses your parameter.
I'm trying to insert some test data into a table to check the functionality of a web servlet, however, using pgAdmin4 to do the insert, I am running into an issue I'm not sure how to rectify. What I want to see is the last value (an image byte stream) is null for this test info. Here is my insert statement:
INSERT INTO schema.tablename("Test Title", "Test Content", "OldWhovian", "2016-07-29 09:13:00", "1469808871694", "null");
I get back:
ERROR: syntax error at or near ";"
LINE 1: ...ldWhovian", "2016-07-29 09:13:00", "1469808871694", "null");
^
********** Error **********
ERROR: syntax error at or near ";"
SQL state: 42601
Character: 122
I've tried removing the semi-colon just for kicks, and it instead errors on the close parenthesis. Is it an issue related to the null? I tried doing this without putting quotations around the null and I get back the same error but on the null instead of the semi-colon. Any help is appreciated, I am new to DBA/DBD related activities.
Related: Using PostgreSql 9.6
The insert statement usually has first part where you specify into which columns you want to insert and second part where you specify what values you want to insert.
INSERT INTO table_name (column1, column2) VALUES (value1, value2);
You do not need to specify into which columns part only if you supply all values in the second part. If you have a table with seven columns you can omit the first part if in the second part you supply seven values.
INSERT INTO table_name VALUES (value1, value2, value3, ...);
Example:
drop table if exists my_table;
create table my_table (
id int not null,
username varchar(10) not null,
nockname varchar(10),
created timestamptz
);
INSERT INTO my_table (id, username) VALUES (1, 'user01');
You insert into columns id and username. The column created has default value specified so when you do not supply value in insert the default is used instead. Nickname and identification_number can accept null values. When no value is supplied NULL is used.
INSERT INTO my_table VALUES (2, 'user02', NULL, NULL, current_timestamp);
That is the same as the previous but here is omitted the fist part so you must supply values for all columns. If you did not you would get an error.
If you want insert multiple values you can use several statements.
INSERT INTO my_table (id, username, identification_number) VALUES (3, 'user03', 'BD5678');
INSERT INTO my_table (id, username, created) VALUES (4, 'user04', '2016-07-30 09:26:57');
Or you can use the postgres simplification for such inserts.
INSERT INTO my_table (id, username, nickname, identification_number) VALUES
(5, 'user05', 'fifth', 'SX59445'),
(6, 'user06', NULL, NULL),
(7, 'user07', NULL, 'AG1123');
At the beginning I have written that you can omit the first part (where you specify columns) only if you supply values for all columns in the second part. It is not completely true. In special cases when you have table that has nullable columns (columns that can contain NULL value) or you have specified DEFAUL values you can also omit the first part.
create sequence my_seq start 101;
create table my_table2 (
id int not null default nextval('my_seq'),
username varchar(10) not null default 'default',
nickname varchar(10),
identification_number varchar(10),
created timestamptz default current_timestamp
);
INSERT INTO my_table2 DEFAULT VALUES;
INSERT INTO my_table2 DEFAULT VALUES;
INSERT INTO my_table2 DEFAULT VALUES;
Result:
101 default NULL NULL 2016-07-30 10:28:27.797+02
102 default NULL NULL 2016-07-30 10:28:27.797+02
103 default NULL NULL 2016-07-30 10:28:27.797+02
When you do not specify values defaults are used or null. In the example above the id column has default value from sequence, username has default string "default", nickname and identification_number are null if not specified and created has default value current timestamp.
More information:
PostgreSQL INSERT
I have one table, which has a filed. When I insert in that table with the Empty value like '' or null, it should get converted to 'DUMMY-VALUE'.
--Have one table;
CREATE TABLE TEST ( FIELD1 VARCHAR2(50) );
--When I insert ''
INSERT INTO TEST(FIELD1) VALUES('');
SELECT * FROM TEST
--Expected Result 'DUMMY-VALUE' but not NULL
I can apply NVL('','DUMMY-VALUE') in INSERT statement but I am allowed to change CREATE statement only.
For Now, I am handing this with TRIGGER but , wondering if there is any alternative in 11g however I know about DEFAULT ON NULL for oracle 12c.
You can do like this:
create table TEST (FIELD1 VARCHAR2(50) default 'DUMMY-VALUE' );
and when you want to insert
you should insert without that field if the values is NULL or empty
Try this:
CREATE TABLE TEST (FIELD1 VARCHAR2(50) DEFAULT 'DUMMY-VALUE');
then use the DEFAULT keyword in the INSERT statement:
INSERT INTO TEST (FIELD1) VALUES (DEFAULT);
SQLFiddle here
Share and enjoy.