Postgres Insert without ANY VALUES FOR COLUMNS. ALL ARE DEFAULT - sql

I have a table in Postgres that only has default column values (id, created_at).
The only way I can insert into this table is
INSERT INTO pages(id) VALUES(DEFAULT) RETURNING id;
Why can't I do this:
INSERT INTO pages RETURNING id;
Just curious.

You can use either :
INSERT INTO test DEFAULT VALUES returning id;
And all the explanations you want are right here : https://www.postgresql.org/docs/current/sql-insert.html
The syntax of PostgreSQL is quite imposed.
DEFAULT VALUES :
All columns will be filled with their default values. (An OVERRIDING clause is not permitted in this form.)

you need the values keyword, otherwise how would you tell how many rows you want to insert? However, you do not require the field names, so you can shorten your query a (very) little bit:
INSERT INTO pages VALUES(DEFAULT) RETURNING id;

Related

Creating New GUID automatically while inserting a new row to an existing table Not Working

I have an existing table in MS SQL called myTab.
It has the following fields
empno(PK) nchar(10),
age int
Now, i want to add a myGUID column and fill it up with a GUID whenever i insert a new row as well as Updating existing rows.
So i added the statement
ALTER TABLE myTab ADD myGUID uniqueidentifier DEFAULT NewId() NOT NULL;
Updating existing rows works correctly.
But, when i try to insert values,
INSERT INTO myTab VALUES ( 1000, 22 );
It fails, and gives the following message
**Column name or number of supplied values does not match table definition.**
When i do
insert into sourav_test2 values (20055711,23,NEWID());
The above statement works.
I want a GUID to be filled without changing the insert statement. Is it possible via a Trigger or a Function?
Always list the columns you are inserting!
INSERT INTO myTab (empno, age)
VALUES ('1000', 22);
Also use correct types for the values. Unmentioned columns will be assigned their default values, or NULL if there is no explicit default.
Your table has three columns, so if you leave out the column list, then the insert expects three values. You can still set a default, if you want by using the DEFAULT keyword in the VALUES clause:
INSERT INTO myTab (empno, age, myGUID)
VALUES ('1000', 22, DEFAULT);
Sourav's question about triggers got me thinking, so I tried a little test. Why?
Imagine a scenario where an application has already been written with thousands of INSERT statements that leave off the column list. In this case, if you could write an INSTEAD OF INSERT trigger that provides the column list, you could hopefully save yourself from correcting thousands of INSERT statements due to a newly added column.
Off the top of my head, I admittedly did not know if this could work.
So I wrote this little test:
CREATE TABLE tt (ColA varchar(1));
INSERT INTO tt VALUES ('a');
ALTER TABLE tt
ADD ColB uniqueidentifier DEFAULT NEWID();
GO
CREATE TRIGGER tr_tt
ON tt
INSTEAD OF INSERT
AS
INSERT INTO tt (ColA)
SELECT ColA FROM inserted;
GO
INSERT INTO tt VALUES ('a');
SELECT * FROM tt;
DROP TABLE tt;
I also tried a variation of the TRIGGER with the following INSERT just to be thorough:
INSERT INTO tt (ColA, ColB)
SELECT ColA, NEWID() FROM inserted;
The result was the same in both cases: The same error as reported in the question. So to answer the question:
Can't we use a trigger here which can do it?
The answer is NO. Even if you put an INSTEAD OF INSERT TRIGGER on the table, the parser will still not let you write an INSERT..VALUES() statement unless the number and order of VALUES exactly matches the definition of the table. A TRIGGER cannot be used to get around it.
Sooner or later, lazy coding exacts its price.

When inserting a tuple into a table in SQL, does the order of the attributes in the schema matter?

ie. if Students(id,name,major,gpa) is the schema, are the following 2 SQL queries valid?
INSERT
INTO Students(id,name,major,gpa)
VALUES (123, Joe, CPSC, 3.0)
INSERT
INTO Students(name,id,major,gpa)
VALUES (Mike, 505, CPSC, 4.0)
Yes both of the query are correct. And the Values will insert to the column in whatever format your INSERT INTO t_Tablename(column1,column2) is made.
Just to make a check you can do (Assume id is int and Name is varchar)
INSERT INTO Students(id, Name)
VALUES("testString", 1)
which will give you an error, since you're trying to insert a string value to id which accepts an int and vice versa
Yes, the two following queries are Valid. Since you keep the order of your attributes values as described in Students(column1,column2), the query will be ok.
As long as the order in the INTO expression equates to the order in the VALUES expression, that is all that is required. The column list in the INTO expression determines both which columns you're specifying values for and the order the values will appear in the VALUES expression. The first column gets the first value, the second gets the second value, and so on.
If you neglect to specify the column list in the INTO expression, most RDBMSs will assume that the columns in the VALUES expression are in the ordinal order of columns in the table itself. That is, if you do this:
INSERT INTO Students
VALUES (123, Joe, CPSC, 3.0)
Then you better have done something like this:
CREATE TABLE Students (id int, name varchar(30), major varchar(30), gpa numeric(3,2))
That's the only time that the order of columns in the table itself actually matters to an INSERT statement.

Use INSERT-OUTPUT to provide values for another INSERT

Good day,
I was wondering if it is possible to use an INSERT-OUTPUT statement in such a way as to provide the value(s) for another, outer, INSERT statement. That way values can be added to an entity table and an intersection table in a single statement - I hope I'm wording this effectively. For example:
INSERT INTO [#tblIntersect] ([Entity1ID], [Entity2ID])
VALUES
(
INSERT INTO [#tblEntity1] ([Value])
OUTPUT [inserted].[ID] AS [entity1ID], #entity2ID AS [entity2ID]
VALUES ('One')
)
So the inner INSERT-OUTPUT statement will add a new entity to table #tblEntity1. The new entity's ID (which is set as IDENTITY(1, 1) will then be returned through the OUTPUT statement, along with a static value (which I already have in my code), to provide the two values for the outer INSERT statement.
The reason I think it might be possible is because execution of the inner INSERT-OUTPUT statement on its own returns a table anyway, and such output can usually be used to provide values for INSERT statements.
Obviously this example doesn't work; I was hoping it's just a simple syntax problem.
Thank you in advance for any comments and advice.
Your requirement is possible according to the documentation.
Assuming #tblIntersect has two matching id columns this should work
INSERT INTO [#tblEntity1] ([Value])
OUTPUT [inserted].[ID] AS [entity1ID], #entity2ID AS [entity2ID]
INTO #tblIntersect
VALUES ('One')

How do I get the value of the autogenerated fields using Postgresql?

I have a postgres table like this:
CREATE SEQUENCE seq;
CREATE TABLE tbl (id INTEGER DEFAULT VALUE nextval('seq'), data VARCHAR);
When I insert into the table:
INSERT INTO tbl (data) VALUES ('something');
How can I get back the value of the id field for the record I just created?
(Note, I may have got some of the SQL syntax a bit off; the gist should be clear, though)
Suppose for the sake of argument that I'm not able to call currval on the same session because I don't control the transaction boundaries. I might be working in the same session with my next call, but I might not be, too.
You're looking for INSERT ... RETURNING. From The Manual's section on INSERT:
The optional RETURNING clause causes INSERT to compute and return value(s) based on each row actually inserted. This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number. However, any expression using the table's columns is allowed. The syntax of the RETURNING list is identical to that of the output list of SELECT.
In the same session:
SELECT currval('seq');
EDIT: But if you can't use currval/nextval because you don't know if the inserting and selecting of the sequence value will occur in the same session, and if you're on postgresql 8.2 or later, you could probably write your insert statement like this.
INSERT INTO tbl (data) VALUES ('something') RETURNING id;
which should also return the last inserted id.
Use nextval and currval, take a look here: http://www.postgresql.org/docs/8.0/static/functions-sequence.html

SQL: Insert multiple sets of values in one statement?

Is it possible to insert multiple sets of values to a SQLite table in one statement?
I was trying:
INSERT INTO the_table VALUES (1,2,'hi'),(2,0,'foo');
with the different ()s representing different insert sets, but I get an error.
Are there only three columns in your table? If not, you could try defining the column names you are setting like so:
INSERT INTO the_table
(column1 ,column2 ,column3)
VALUES (1 ,2 ,'hi' )
,(2 ,0 ,'foo' )
This convention was introduced in SQL Server 2008 known as the Table Value Constructor. See MSDN's INSERT page for a look at the overall syntax. Also, the INSERT statement can be easily formatted for better readability.
You can do
INSERT INTO the_table
SELECT 1,2,'hi'
UNION
SELECT 2,0,'foo';
I was found that syntax in MSDN but after trying I can't do that too, than I note that in the bottom of the page was written that there is an error in the page :) where is link http://msdn.microsoft.com/en-us/library/ms174335.aspx see the bottom How to insert multiple rows