Question: Is there a way to insert a row in PostgreSQL table using the default values for all columns without specifying any column name?
Background: If I have a table with two columns that both have default values (or simply accept NULL), I can omit the column name when I insert a row if I wish the value for that column to be the default value. For instance:
CREATE TABLE test_table ( column1 TEXT, column2 TEXT );
I can insert into the table by only specifying a value for column1 or column2 and the missing column will be populated with the default value (NULL in this case):
INSERT INTO test_table (column1) VALUES ('foo');
INSERT INTO test_table (column2) VALUES ('bar');
The above will result in two rows: [('foo', NULL), (NULL, 'bar')]. However, if I want to use the default value for both columns, it seems that I have to specify at least one column name and explicitly give it the default value. The follow commands are all legal:
INSERT INTO test_table (column1) VALUES (DEFAULT);
INSERT INTO test_table (column2) VALUES (DEFAULT);
INSERT INTO test_table (column1, column2) VALUES (DEFAULT, DEFAULT);
I was unable to create a valid command that allowed me to omit all column names. The following attempts are all illegal:
INSERT INTO test_table;
INSERT INTO test_table () VALUES ();
Is there a way to do this or is it explicitly forbidden? I wasn't able to find any documentation for a case like this. Thanks!
I found that there is special syntax for this exact use-case:
INSERT INTO test_table DEFAULT VALUES;
Related
Let sample_table be the following postgres 9.6.6 table:
CREATE TABLE sample_table (
col_a integer,
col_b integer
);
Is it possible to add constraints to sample_table to ensure that, on every one of its rows with col_b=42, no value on col_a appears twice?
You could add a conditional index (which can not be converted to a constraint, but works as if):
CREATE UNIQUE INDEX ON sample_table(col_a)
WHERE col_b=42;
I would prefer col_a to be NOT NULLable
I have created these two tables:
CREATE TABLE Purchase(
purchaseID SERIAL,
custName VARCHAR(30) NOT null,
PRIMARY KEY (purchaseID));
CREATE TABLE PurchasedItem(
purchaseID INT,
itemNo INT NOT NULL,
PRIMARY KEY (purchaseID, itemNo),
FOREIGN KEY (purchaseID) REFERENCES Purchase(purchaseID));
Next I wish to insert data into both tables, with the purchaseID foreign key of purchased item having the same value as the purchaseID Serial from Purchase table.
I am using a PostgreSQL client called PSequel. I tried setting AUTOCOMMIT to off first in the client so I could have the two INSERT statement in the same transaction, however the client didn't recognise "autocommit", so I tried it in the terminal and I think it worked... anyway, these are the two INSERT statements I tried.
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo) VALUES (DEFAULT, 111);
commit;
However I get an error:
ERROR: null value in column purchaseID violates not-null constraint.
this is referring to the PurchasedItem's purchaseID as in running the first INSERT statement by itself it works. How do I solve this problem?
DEFAULT will work for SERIAL as it sets default value for column. So
INSERT INTO Purchase VALUES (DEFAULT,'Lendl');
should work. But PurchasedItem.purchaseID has no default value set, so it it tries to insert NULL (and null is not in referenced column yet), so it fails.
try:
INSERT INTO Purchase(custName) VALUES ('Lendl') RETURNING purchaseID;
you will see the value of inserted purchaseID, use it in next query:
INSERT INTO PurchasedItem(purchaseID, itemNo) VALUES (_the_value_above_, 111);
commit;
If you want it to be used without interactivity, use DO block with returning purchaseID into _value
update:
or cte, smth like
WITH i AS (
INSERT INTO Purchase(custName, orderedDate)
VALUES ('Lendl', '2016-09-28')
RETURNING purchaseID
)
insert into PurchasedItem
select i.purchaseID,'smth',3
from i
You can use lastval()
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo) VALUES (lastval(), 111);
commit;
Alternatively query the underlying sequence directly:
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo)
VALUES (currval('purchase_purchaseid_seq'), 111);
commit;
Or if you don't want to rely on the automatic naming of the sequence, use pg_get_serial_sequence to get the sequence associated with the column:
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo)
VALUES (currval(pg_get_serial_sequence('purchase', 'purchaseid')), 111);
commit;
For more details see the manual: https://www.postgresql.org/docs/current/static/functions-sequence.html
I have a simple test table
CREATE TABLE TEST (
KEY INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
INTENTS VARCHAR(255),
NO_FOUND SMALLINT );
I am then trying to insert data into this table using the following command from within dashDB's sql dashboard.
Insert into table from (select item1,item2,item3 from TEST2 where some_condition );
However I cannot seem to get the command to not return an error.
Have tried the db2 'DEFAULT', and '0' (default for integer), and even NULL as values for item1.
Have also tried the insert using values, but then the column headings cause the system to report multiple values returned.
Have also tried 'OVERRIDING USER VALUE'
but this then complains about not finding a JOIN element.
Any ideas welcome.
I would try something like this:
Insert into test(intents,no_found)
(select item2,item3 from TEST2 where some_condition );
You specify that only two of the three columns receive values, the KEY column is generated. Hence you only select the two related columns.
I have a simple table (4 text columns, and an ID column). I am trying to import my CSV file which has no ID column.
In Postico I have the schema setup as such:
DROP TABLE changes;
CREATE TABLE changes(
id SERIAL PRIMARY KEY,
commit_id TEXT,
additions INTEGER,
deletions INTEGER,
file_id TEXT
);
CREATE TEMP TABLE tmp_x AS SELECT * FROM changes LIMIT 0;
COPY tmp_x(commit_id,additions,deletions,file_id) FROM '/Users/George/git-parser/change_file' (format csv, delimiter E'\t');
INSERT INTO changes SELECT * FROM tmp_x
ON CONFLICT DO NOTHING;
DROP TABLE tmp_x;
But I am getting the error ERROR: null value in column "id" violates not-null constraint
You need to specify the columns:
COPY tmp_x (commit_id, additions, deletions, file_id)
FROM '/Users/George/git-parser/change_file' (format csv, delimiter E'\t');
The order of columns specified in the copy statement must obviously match the order of the columns in the input file.
You need to change your insert statement as well.
INSERT INTO changes SELECT * FROM tmp_x
will insert all columns from tmp_x into the target table, but as you did not define the id column as serial in the tmp_x table, nothing got generated and null values were inserted. And your insert statement just copies those null values.
You need to skip the id column in the insert statement:
INSERT INTO changes (commit_id,additions,deletions,file_id)
SELECT commit_id,additions,deletions,file_id
FROM tmp_x
ON CONFLICT DO NOTHING;
You can actually remove the id column from tmp_x
I am trying to do what is described in this solution and also here. That means I would like to copy rows with many columns while changing only a few values. So my query looks like this:
CREATE TEMPORARY TABLE temp_table AS
SELECT * FROM original_table WHERE <conditions>;
UPDATE temp_table
SET <auto_inc_field>=NULL,
<fieldx>=<valuex>,
<fieldy>=<valuey>;
INSERT INTO original_table SELECT * FROM temporary_table;
However, the <auto_inc_field>=NULL part is not working for me, respectively my PostgreSQL 9.4 database:
Exception: null value in column "auto_inc_field" violates not-null constraint
The <auto_inc_field> column is defined as BIGINT, SERIAL, and has a primary key constraint.
What do I need to pass, if NULL is not working? Is there an alternative method?
I understand that the primary key is a serial. List all columns but the primary key in the insert command. List the correspondent columns and values in the select command:
insert into original_table (col_1, col_2, col_3)
select col_1, value_2, value_2
from original_table
where the_conditions;