I created a table in DBBrowser:
CREATE VIRTUAL TABLE IF NOT EXISTS Students USING FTS5
(
GroupId UNINDEXED,
StudentName
);
and insert values to it. After that I add DB with this table to my project.
It is declaration of this table in sqldelight .sq file:
CREATE VIRTUAL TABLE IF NOT EXISTS Students USING FTS5
(
GroupId INTEGER AS Int,
StudentName TEXT,
rank REAL
);
I need to explicit declare rank because I want to apply HAVING MIN(rank) for it when SELECT from table (otherwise it is not compile), but when I trying to insert values in table like that:
insert:
INSERT INTO Students VALUES (?,?);
I receive an error:
Unexpected number of values being inserted. found: 2 expected: 3
If I do like that:
insert:
INSERT INTO Students VALUES (?,?,?);
I receive an exception:
SQLiteException - table Students has 2 columns but 3 values were supplied (code 1): , while compiling: INSERT INTO Students VALUES (?,?,?)
How I can perform insert? Or maybe I can apply HAVING MIN(rank) without explicit declare?
does
insert:
INSERT INTO Students(GroupId, StudentName) VALUES (?,?);
work?
Related
This question already has answers here:
Is it possible to for SQL Output clause to return a column not being inserted?
(2 answers)
Closed 2 years ago.
Microsoft's OUTPUT Clause documentation says that you are allowed to use from_table_name in the OUTPUT clause's column name.
There are two examples of this:
Using OUTPUT INTO with from_table_name in an UPDATE statement
Using OUTPUT INTO with from_table_name in a DELETE statement
Is it possible to also use it in an INSERT statement?
INSERT INTO T ( [Name] )
OUTPUT S.Code, inserted.Id INTO #TMP -- The multi-part identifier "S.Code" could not be bound.
SELECT [Name] FROM S;
Failing example using table variables
-- A table to insert into.
DECLARE #Item TABLE (
[Id] [int] IDENTITY(1,1),
[Name] varchar(100)
);
-- A table variable to store inserted Ids and related Codes
DECLARE #T TABLE (
Code varchar(10),
ItemId int
);
-- Insert some new items
WITH S ([Name], Code) AS (
SELECT 'First', 'foo'
UNION ALL SELECT 'Second', 'bar'
-- Etc.
)
INSERT INTO #Item ( [Name] )
OUTPUT S.Code, inserted.Id INTO #T -- The multi-part identifier "S.Code" could not be bound.
SELECT [Name] FROM S;
No, because an INSERT doesn't have a FROM; it has a set of values that are prepared either by the VALUES keyword, or from a query (and even though that query has a FROM, you should conceive that it's already been run and turned into a block of values by the time the insert is done; there is no s.code any more)
If you want to output something from the table that drove the insert you'll need to use a merge statement that never matches any records (so it's only inserting) instead, or perhaps insert all your data into #tmp and then insert from #tmp into the real table - #tmp will thus still be the record of rows that were inserted, it's just that it was created to drive the insert rather than as a consequence of it (caveats that it wouldn't contain calculated columns)
I have some temp table:
CREATE TEMP TABLE IF NOT EXISTS temp_test (
col1 INTEGER NOT NULL,
col2 CHARACTER VARYING NOT NULL,
col3 BOOLEAN);
Then I do some inserts into temp_test (that works fine).
Later, without creating a new table test, I try doing the following:
INSERT INTO test(col1,col2,col3) SELECT col1,col2,col3 FROM temp_tes;
And I get the following error:
ERROR: relation "test" does not exist
I thought that if I'm using INSERT INTO, it should create the table for me. does it not?
If it matters, I'm using PostgreSQL 9.6.16.
You are wrong. INSERT inserts into an existing table; it does not create a table.
If you want to create a table, use CREATE TABLE AS:
CREATE TABLE test AS
SELECT col1, ol2, col3
FROM temp_tes;
In postgres I have two tables like so
CREATE TABLE foo (
pkey SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE bar (
pkey SERIAL PRIMARY KEY,
foo_fk INTEGER REFERENCES foo(pkey) NOT NULL,
other TEXT
);
What I want to do is to write a .sql script file that does the following
INSERT INTO foo(name) VALUES ('A') RETURNING pkey AS abc;
INSERT INTO bar(foo_fk,other) VALUES
(abc, 'other1'),
(abc, 'other2'),
(abc, 'other3');
which produces the error below in pgAdmin
Query result with 1 row discarded.
ERROR: column "abc" does not exist
LINE 3: (abc, 'other1'),
********** Error **********
ERROR: column "abc" does not exist
SQL state: 42703
Character: 122
Outside of a stored procedure how do a define a variable that I can use between statements? Is there some other syntax for being able to insert into bar with the pkey returned from the insert to foo.
You can combine the queries into one. Something like:
with foo_ins as (INSERT INTO foo(name)
VALUES ('A')
RETURNING pkey AS foo_id)
INSERT INTO bar(foo_fk,other)
SELECT foo_id, 'other1' FROM foo_ins
UNION ALL
SELECT foo_id, 'other2' FROM foo_ins
UNION ALL
SELECT foo_id, 'other3' FROM foo_ins;
Other option - use an anonymous PL/pgSQL block like:
DO $$
DECLARE foo_id INTEGER;
BEGIN
INSERT INTO foo(name)
VALUES ('A')
RETURNING pkey INTO foo_id;
INSERT INTO bar(foo_fk,other)
VALUES (foo_id, 'other1'),
(foo_id, 'other2'),
(foo_id, 'other3');
END$$;
You can use lastval() to ...
Return the value most recently returned by nextval in the current session.
This way you do not need to know the name of the seqence used.
INSERT INTO foo(name) VALUES ('A');
INSERT INTO bar(foo_fk,other) VALUES
(lastval(), 'other1')
, (lastval(), 'other2')
, (lastval(), 'other3')
;
This is safe because you control what you called last in your own session.
If you use a writable CTE as proposed by #Ihor, you can still use a short VALUES expression in the 2nd INSERT. Combine it with a CROSS JOIN (or append the CTE name after a comma (, ins) - same thing):
WITH ins AS (
INSERT INTO foo(name)
VALUES ('A')
RETURNING pkey
)
INSERT INTO bar(foo_fk, other)
SELECT ins.pkey, o.other
FROM (
VALUES
('other1'::text)
, ('other2')
, ('other3')
) o(other)
CROSS JOIN ins;
Another option is to use currval
INSERT INTO foo
(name)
VALUES
('A') ;
INSERT INTO bar
(foo_fk,other)
VALUES
(currval('foo_pkey_seq'), 'other1'),
(currval('foo_pkey_seq'), 'other2'),
(currval('foo_pkey_seq'), 'other3');
The automatically created sequence for serial columns is always named <table>_<column>_seq
Edit:
A more "robust" alternative is to use pg_get_serial_sequence as Igor pointed out.
INSERT INTO bar
(foo_fk,other)
VALUES
(currval(pg_get_serial_sequence('public.foo', 'pkey')), 'other1'),
(currval(pg_get_serial_sequence('public.foo', 'pkey')), 'other2'),
(currval(pg_get_serial_sequence('public.foo', 'pkey')), 'other3');
I create a table and sequence in order to replace identity in the table I use SQL Server 2012 Express but I get this error while I tried to insert data to the table
Msg 11719, Level 15, State 1, Line 2
NEXT VALUE FOR function is not allowed in check constraints, default objects, computed columns,
views, user-defined functions, user-defined aggregates, user-defined
table types, sub-queries, common table expressions, or derived
tables.
T-SQL code:
insert into Job_Update_Log(log_id, update_reason, jobid)
values((select next value for Job_Log_Update_SEQ),'grammer fixing',39);
This is my table:
create table Job_Update_Log
(
log_id int primary key ,
update_reason nvarchar(100) ,
update_date date default getdate(),
jobid bigint not null,
foreign key(jobid) references jobslist(jobid)
);
and this is my sequence:
CREATE SEQUENCE [dbo].[Job_Log_Update_SEQ]
AS [int]
START WITH 1
INCREMENT BY 1
NO CACHE
GO
Just get rid of the subselect in the VALUES section, like this:
insert into Job_Update_Log(log_id,update_reason,jobid)
values (next value for Job_Log_Update_SEQ,'grammer fixing',39);
Reference: http://msdn.microsoft.com/en-us/library/hh272694%28v=vs.103%29.aspx
Your insert syntax appears to be wrong. You are attempting to use a SELECT statement inside of the VALUES section of your query. If you want to use SELECT then you will use:
insert into Job_Update_Log(log_id,update_reason,jobid)
select next value for Job_Log_Update_SEQ,'grammer fixing',39;
See SQL Fiddle with Demo
I changed the syntax from INSERT INTO VALUES to INSERT INTO ... SELECT. I used this because you are selecting the next value of the sequence.
However, if you want to use the INSERT INTO.. VALUES, you will have to remove the SELECT from the query:
insert into Job_Update_Log(log_id,update_reason,jobid)
values(next value for Job_Log_Update_SEQ,'grammer fixing',39);
See SQL Fiddle with Demo
Both of these will INSERT the record into the table.
Try this one:
–With a table
create sequence idsequence
start with 1 increment by 3
create table Products_ext
(
id int,
Name varchar(50)
);
INSERT dbo.Products_ext (Id, Name)
VALUES (NEXT VALUE FOR dbo.idsequence, ‘ProductItem’);
select * from Products_ext;
/* If you run the above statement two types, you will get the following:-
1 ProductItem
4 ProductItem
*/
drop table Products_ext;
drop sequence idsequence;
------------------------------
I have created table using this command successfully
create table Person(
first_name varchar(25) not null,
last_name varchar(25) not null,
persoin_id number not null,
birth_date date,
country varchar (25),
salary number);
and now I want to insert data into that table
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia');
values(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia');
first row is inserted,but problem is with second line
1 rows inserted.
Error starting at line 10 in command:
values(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia')
Error report:
Unknown Command
Please help me to determine what is problem?thanks
If you are on a RDBMS that supports multi-rows inserts in one INSERT:
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values
(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia') ,
--- comma here ---^
(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia') ;
^--- no "values" here
If not (like Oracle), you'll have to issue two insert statements:
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values
(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia') ;
--- as it was here ---^
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values
(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia') ;
or use this approach:
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
select
(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia')
from dual
union all select
(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia')
from dual
;
You will need to use 2 insert statement instead of one for 2 different sets of data...
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia');
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia')
You have a ; at the end of:
values(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia');
^
change it to , and also loose the values from the next line. You need just one values per insert.