Auto incrementing delta table id with START INCREMENT by - apache-spark-sql

When I try to generate a default increment it works just fine, but adding START WITH, INCREMENT BY throws an error. I'm using DB 11.3 so it should be supported, pic with error attached

The square brackets are used to identify optional values - took me a few tries to get the syntax right...
%sql CREATE
OR REPLACE TABLE products (
product_id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 100 INCREMENT BY 1),
product_type STRING,
sales BIGINT
);
INSERT INTO products (product_type, sales)
VALUES ("Batteries", 150000);
INSERT INTO products (product_type, sales)
VALUES ("lAPTOP", 100000);
Hope it helps...

Related

Whats wrong on my Postgres insert or update query

I want to insert or update data to a table. The column "Group" is UNIQUE and the ID of the group should remain constant.
there Is a Fiddle:
http://sqlfiddle.com/#!17/551ea/3
on Insert, everything is okay
also the Update works for "Group" = 'TEST01'
But when I insert a new group and then update, the ID changes (press multiple "Run SQL")
This is my insert query:
INSERT INTO GROUPS ("GROUP", SERVER, PATH, SHARE)
VALUES ('TEST04', 4, 4, 4)
ON CONFLICT("GROUP") DO UPDATE
SET SERVER = 11,
PATH = 11,
SHARE = 11
WHERE GROUPS."GROUP" = 'TEST01'
The ID will be used in other tables, this should only be created once for the first entry.
and this is the general structure:
CREATE SEQUENCE gid START 1;
CREATE TABLE GROUPS (
ID integer NOT NULL DEFAULT nextval('gid') PRIMARY KEY,
"GROUP" VARCHAR NOT NULL UNIQUE,
SERVER integer,
PATH integer,
SHARE integer
);
Look at this fiddle
Each time there is a conflict on insert - the sequence value is discarded and ON UPDATE requests a new value. So initially you start with 1, then you insert 3 tuples so the final value of the sequence would be 3. Then you try to insert a new tuple but there is a conflict - so the value of sequence is now 4. Then you try to insert a new tuple - and it gets a value of 5 for the sequence.
If you continue to run the 2 inserts the sequence will continue to increment. SQLfiddle probably uses persistent connections or some connection pooling which does not properly reset the sequence when rebuilding the schema.

Sqlite3 trigger with UPSERT

I'm using sqlite3 on my Rails project and I need to create a trigger that automatically inserts into the table when another referencing table is updated.
For example, I have 2 tables Breakdown and Total, schemas for each table are as below.
Breakdown
Date TEXT NOT NULL,
Amount DECIMAL NOT NULL
Total
Date TEXT NOT NULL,
Daily_Total DECIMAL NOT NULL,
FOREIGN KEY (Date) REFERENCES Breakdown(Date)
Then, below is my trigger creation.
CREATE TRIGGER update_sum AFTER INSERT ON Breakdown
...> BEGIN
...> INSERT OR REPLACE INTO Total (Date, Daily_Total)
...> VALUES (Breakdown.Date,
...> (SELECT SUM(Amount) FROM Breakdown WHERE Date = Total.Date));
...> END;
So, my idea is when I insert into Breakdown table as **INSERT INTO Breakdown VALUES (Date('now'),19.99);** then Total table gets updated by either inserting or update.
However, when I insert into Breakdown table, I get an error saying Error: no such column: Breakdown.Date
Can anyone direct me to the point where I'm doing wrong, please?
Thank you!
You can access the values of the row that caused the trigger to trigger, but that 'table' is called NEW:
INSERT ... VALUES(NEW.Date, (SELECT SUM... WHERE Date = NEW.Date));

Insert query failing with a Syntax error while trying to run it

Movie Table has 4 Attributes: movie_id, moive_name, desc, genre_id
movie_id (autoNumber) PK
moive_name(short Text)
desc(long Text)
genre_id(number) FK
This is the query I am trying to run
INSERT INTO Movie (moive_name,description,genre_id)
VALUES('Rise','dfdsfsa','1')
I know moive_name is miss spelled but its like that in the db aswell will fix it later.
I am still getting a systax error
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Syntax error in INSERT INTO statement.
I am sure the table is called Movie. I left out the movie_id field since I want it to auto fill with the next number as its autoNumber. Do you guys maybe know what I am doing wrong?
In your table have four values , but you are trying to insert with three values.
It won't work in oracle.Create Movie_id as a primary key without auto increment and create sequence for your movie id
CREATE SEQUENCE movie_id
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10
and try this insert statement
INSERT INTO Movie (movie_id,moive_name,description,genre_id)
VALUES(movie_id.nextval,'Rise','dfdsfsa','1')
i think you are trying to insert a string in number '1' should be like 1
INSERT INTO Movie (moive_name,description,genre_id)
VALUES('Rise','dfdsfsa',1)
Hi Tristan,Provide genre_id without single codes as it is a numeric value. Not sure how you are generating movie_id, if it is a sequence number, provide the number
INSERT INTO Movie (movie_id,moive_name,description,genre_id)
VALUES (your_movie_id,'Rise','dfdsfsa',1)

Insert or Replace with sum of old values

I am building Inventory Application using PhoneGap.In that i have one module STOCK for stock management.
Stock Table Query
CREATE TABLE STOCK (
sto_id INTEGER PRIMARY KEY AUTOINCREMENT,
pro_id INTEGER FOREIGNKEY REFERENCES PRODUCT(pro_id) UNIQUE,
quantity TEXT
)
INSERT OR REPLACE Query
INSERT OR REPLACE INTO STOCK (pro_id,quantity) VALUES ("1","5");
There is not a single issue with this query its working perfectly but i want to update SUM of OLD VALUES WITH NEW ONE.
Example:
pro_id quantity
1 5
This is existing record so now when i will fire above query for new transaction which have 3 quantity then quantity should be (5 (old) + 3 (new) ) = 8.
So after updateing record it looks like.
pro_id quantity
1 8
How can i solve this any idea. or let me know if i am on wrong way.
Thanks.
Actually I am not real founder of this solution. The real hero is Daverandom with the help of him i have solve my issue.
He has suggest me to follow this solution and that is really helpful to find my solution.
Older query looks like as
INSERT OR REPLACE INTO STOCK (pro_id,quantity) VALUES ("1","5");
New Query looks like as
INSERT OR IGNORE INTO STOCK (pro_id,quantity) VALUES (1,0) ;
UPDATE STOCK SET quantity = quantity + 2 WHERE pro_id=1;
Update:
If you will not add WHERE pro_id="val" in UPDATE then it will UPDATE all rows.
So that will generate will appropriate result.
When user fire query first time then quantity will be 2 and when you fire same query second time it will 4.
So, We can change that value in each update.
Again thanks to Daverandom.
In SQLite, you can create a trigger to handle such functionality:
CREATE TRIGGER t1 BEFORE INSERT ON STOCK WHEN NEW.pro_id IN (SELECT pro_id FROM STOCK) BEGIN
UPDATE STOCK SET quantity=COALESCE(NEW.quantity, 0)+COALESCE((SELECT quantity FROM STOCK WHERE pro_id=NEW.pro_id), 0) WHERE pro_id=NEW.pro_id;
SELECT RAISE(IGNORE); -- Ignore INSERT
END;
From now on, whenever you try to insert an existing pro_id, update on quantity is done instead. Conflict clause (OR REPLACE) doesn't matter as trigger will handle it (for pro_id).
Yet another, this time without triggers, using single statement solution:
INSERT OR REPLACE STOCK(pro_id, quantity)
SELECT npro_id, COALESCE(nqty, 0)+COALESCE(quantity,0) FROM (
SELECT 123 AS npro_id, 9999 AS nqty
) LEFT JOIN STOCK ON npro_id=pro_id;
Just replace 123 with new prod_id and 9999 with new quantity.

SQLite auto-increment non-primary key field

Is it possible to have a non-primary key to be auto-incremented with every insertion?
For example, I want to have a log, where every log entry has a primary key (for internal use), and a revision number ( a INT value that I want to be auto-incremented).
As a workaround, this could be done with a sequence, yet I believe that sequences are not supported in SQLite.
You can do select max(id)+1 when you do the insertion.
For example:
INSERT INTO Log (id, rev_no, description)
VALUES ((SELECT MAX(id) + 1 FROM log), 'rev_Id', 'some description')
Note that this will fail on an empty table since there won't be a record with id is 0 but you can either add a first dummy entry or change the sql statement to this:
INSERT INTO Log (id, rev_no, description)
VALUES ((SELECT IFNULL(MAX(id), 0) + 1 FROM Log), 'rev_Id', 'some description')
SQLite creates a unique row id (rowid) automatically. This field is usually left out when you use "select * ...", but you can fetch this id by using "select rowid,* ...". Be aware that according to the SQLite documentation, they discourage the use of autoincrement.
create table myTable ( code text, description text );
insert into myTable values ( 'X', 'some descr.' );
select rowid, * from myTable;
:: Result will be;
1|X|some descr.
If you use this id as a foreign key, you can export rowid - AND import the correct value in order to keep data integrity;
insert into myTable values( rowid, code text, description text ) values
( 1894, 'X', 'some descr.' );
You could use a trigger (http://www.sqlite.org/lang_createtrigger.html) that checks the previous highest value and then increments it, or if you are doing your inserts through in a stored procedure, put that same logic in there.
My answer is very similar to Icarus's so I no need to mention it.
You can use Icarus's solution in a more advanced way if needed. Below is an example of seat availiabilty table for a train reservation system.
insert into Availiability (date,trainid,stationid,coach,seatno)
values (
'11-NOV-2013',
12076,
'SRR',
1,
(select max(seatno)+1
from Availiability
where date='11-NOV-2013'
and trainid=12076
and stationid='SRR'
and coach=1)
);
You can use an AFTER INSERT trigger to emulate a sequence in SQLite (but note that numbers might be reused if rows are deleted). This will make your INSERT INTO statement a lot easier.
In the following example, the revision column will be auto-incremented (unless the INSERT INTO statement explicitly provides a value for it, of course):
CREATE TABLE test (
id INTEGER PRIMARY KEY NOT NULL,
revision INTEGER,
description TEXT NOT NULL
);
CREATE TRIGGER auto_increment_trigger
AFTER INSERT ON test
WHEN new.revision IS NULL
BEGIN
UPDATE test
SET revision = (SELECT IFNULL(MAX(revision), 0) + 1 FROM test)
WHERE id = new.id;
END;
Now you can simply insert a new row like this, and the revision column will be auto-incremented:
INSERT INTO test (description) VALUES ('some description');