I've been working with teradata for couple of months.
However cannot understand how correctly create auto-incrementing ID.
Serfing the internet I found the most clear and well-working for me the way to create id column as auto generated:
CREATE TABLE tbl_emp (
id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 1
INCREMENT BY 1
MINVALUE 0
MAXVALUE 1000000
NO CYCLE),
Name VARCHAR(20),
Phone VARCHAR(10));
But it seems that exists another way to do the same by adding 'primary index (id)':
CREATE TABLE tbl_emp (
id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 1
INCREMENT BY 1
MINVALUE 0
MAXVALUE 1000000
NO CYCLE),
Name VARCHAR(20),
Phone VARCHAR(10)) primary index (id);
I am a bit confused. What is actual difference between this 2 queries? What will be the result?
Related
Did anyone work on react native expo's sqlite database with foreign key constraints? Can we use structure similar to sql?
I'm trying to work on it building multiple tables with foreign key condition.
Example: If we have 2 tables Persons and Orders where personID is referred as foreign key in orders table. How would it be done using sqlite?
You would have two tables, perhaps with a column as the alias of the rowid column, this
e.g.
CREATE TABLE persons (
personid INTEGER PRIMARY KEY,
personname TEXT
);
CREATE TABLE orders (
orderid INTEGER PRIMARY KEY,
ordername TEXT,
person_reference INTEGER REFERENCES persons(personid)
);
Note that you have to turn foreign key handling on e.g. by executing PRAGMA foreign_keys = ON; (or true). See PRAGMA foreign_keys
in SQLite coding column_name INTEGER PRIMARY KEY defines that column as an alias of the rowid column, and if a value is not provided for the column when inserting then an integer value will be assigned. The initial value for the first row will be 1, subsequent values will typically be 1 greater than the highest rowid value (read the link above in regards why the word typically has been used).
If you then try to insert an Order for a non-existent personid you will then get a Foreign Key conflict.
An alternative to the column level definition would be to define the foreign key(s) at the table level e.g.
CREATE TABLE orders (
orderid INTEGER PRIMARY KEY,
ordername TEXT,
person_reference INTEGER,
FOREIGN KEY (person_reference) REFERENCES persons(personid)
);
As an example, consider the following :-
INSERT INTO persons (personname) VALUES
('Fred'),
('Mary'),
('Sue'),
('Tom')
;
INSERT INTO orders (ordername, person_reference) VALUES
('Order 1 for Fred',1),
('Order 2 for Sue',3),
('Order 3 for Fred',1),
('Order 4 for Mary',2)
;
INSERT into orders (ordername, person_reference) VALUES
('Order 5 for nobody',100);
The result would be :-
INSERT INTO persons (personname) VALUES ('Fred'),('Mary'),('Sue'),('Tom')
> Affected rows: 4
> Time: 0.453s
INSERT INTO orders (ordername, person_reference) VALUES
('Order 1 for Fred',1),('Order 2 for Sue',3),('Order 3 for Fred',1),('Order 4 for Mary',2)
> Affected rows: 4
> Time: 0.084s
INSERT into orders (ordername, person_reference) VALUES
('Order 5 for nobody',100)
> FOREIGN KEY constraint failed
> Time: 0s
i.e. the last as there is no row in the persons table with a personid of 100, then the last insert (on it's own doe demonstration) fails.
You may wish to refer to SQLite Foreign Key Support
I have the following SQLite table:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE
)
Whenever a user inserts/updates a row in the table, I want to sort that row at the end of the table. Thus, if I insert the following values:
_id | search | sort
===================
1 | foo | 1
2 | bar | 2
3 | quiz | 3
And then later update the 1 row from foo to foo2, the values should look like:
_id | search | sort
===================
2 | bar | 2
3 | quiz | 3
1 | foo2 | 4
I've implemented this thusly:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE,
update_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)
CREATE TRIGGER update_date_update_trigger
AFTER UPDATE ON podcast_search FOR EACH ROW
BEGIN
UPDATE podcast_search
SET update_date = CURRENT_TIMESTAMP
WHERE _id = OLD._id;
END
However, my unit tests require a 1000ms sleep between insert/update operations in order to reliably sort, and this amount of delay is very annoying for unit testing.
I thought I could implement a vector clock instead, but it seems that AUTOINCREMENT values only exist for primary key columns. Does SQLite offer any other AUTOINCREMENT or AUTOINCREMENT-like option?
I'm running this on Android P, but this should be a generic SQLite problem.
UPDATE
I'm now using an sort INTEGER NOT NULL UNIQUE column, and SELECT-ing the largest row in that column and manually incrementing it before an INSERT/UPDATE:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE,
sort INTEGER NOT NULL UNIQUE
)
SELECT sort from podcast_search ORDER BY sort DESC
either increment sort in application code, or set it to 0
Could I do this in a TRIGGER instead?
I thought I could implement a vector clock instead, but it seems that
AUTOINCREMENT values only exist for primary key columns. Does SQLite
offer any other AUTOINCREMENT or AUTOINCREMENT-like option?
They are not in fact AUTOINCREMENT values rather a column with AUTOINCREMENT will be an alias of the rowid column; not because AUTOINCREMENT has been coded but because INTEGER PRIMARY KEY has been coded.
All coding AUTOINCREMENT does is add a constraint that an auto-generated value MUST be greater than any other existing or used value. This only in fact becomes apparent if when a rowid with the value of 9223372036854775807 exists. In which case an attempt to insert a new row with an auto-generated rowid (i.e. no value is specified for the rowid column or an alias thereof) will result in an SQLITE_FULL error.
Without AUTOINCREMENT and when the highest rowid is 9223372036854775807 (the highest possible value for a rowid) an attempt is made to use a free value, which would obviously be lower than 9223372036854775807.
SQLite Autoincrement
You may wish to note the very first line of the linked page which says :-
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and
disk I/O overhead and should be avoided if not strictly needed. It is
usually not needed.
I can't see any need from your description.
So what you want is a means of assigning a value for the column that is to be sorted that is 1 greater than the highest current value for that column, so it becomes the latest for sorting purposes, a subquery that retrieves max(the_column) + 1 would do what you wish. This could be in an UPDATE, TRIGGER or in an INSERT.
rowid = max(rowid) + 1 is basically how SQLite assigns a value to rowid unless AUTOINCREMENT is used when 1 is added to the greater of max(rowid) and the value, for the respective table, obtained from the table sqlite_sequence (will only exist if AUTOINCREMENT is used). It is referencing and maintaining sqlite_sequence that incurs the penalties.
For example you could use the following (which eliminates the need for an additional column and the additional index) :-
-- SETUP THE DATA FOR TESTING
DROP TABLE IF EXISTS podcast_searchv1;
CREATE TABLE IF NOT EXISTS podcast_searchv1 (
_id INTEGER NOT NULL PRIMARY KEY,
search TEXT NOT NULL UNIQUE
);
INSERT INTO podcast_searchv1 (search)
VALUES('foo'),('bar'),('guide')
;
-- Show original data
SELECT * FROM podcast_searchv1;
-- DO THE UPDATE
UPDATE podcast_searchv1 SET search = 'new value', _id = (SELECT max(_id) + 1 FROM podcast_searchv1) WHERE search = 'foo';
-- Show the changed data
SELECT * FROM podcast_searchv1;
The results being :-
and then :-
I have a table which has one primary key integer:
CREATE TABLE TBL (ID INTEGER PRIMARYKEY,ZID INTEGER)
That zid integer field that must be incremented from the previous one found in the database.
I could do something like that:
INSERT INTO TBL (zid) VALUES ((SELECT MAX(zid) + 1 FROM TBL));
However, the value of that integer field will, at some point, reset to zero. Therefore I want to increment from the last entry, not necessarily the maximum in the entire table.
How can I do that? A trigger?
Thanks.
how about a query like:
SELECT zid + 1 FROM TBL ORDER BY id DESC LIMIT 1
with this select query you will only get the value from the last line (+1)
I would like to automatically insert a primary key every time I add a new record to an SQLite3 table, much like a PRIMARY KEY AUTOINCREMENT except that the value should be randomly chosen from some range (say 0000 through 9999) rather than being assigned sequentially.
For demonstration purposes, let's restrict the range to 1 through 6 instead and try to populate the following table:
CREATE TABLE dice (rolled INTEGER PRIMARY KEY NOT NULL);
Now every time I insert a new record into that table, I want a new random primary key to be created.
The following works and does exactly what I want
INSERT INTO dice VALUES(
(
WITH RECURSIVE roll(x) AS (
VALUES(ABS(RANDOM()) % 6 + 1)
UNION ALL
SELECT x % 6 + 1 FROM roll
)
SELECT x FROM roll WHERE (
SELECT COUNT(*) FROM dice where rolled = x
) = 0 LIMIT 1
)
);
except that I have to invoke it manually/explicitly.
Is there any way to embed the above (or an equivalent) calculation for the random primary key into a DEFAULT clause for the "rolled" column or into some sort of trigger, so that a new key will be calculated automatically every time I insert a record?
This question already has answers here:
Set a custom identity value on a auto increment field
(2 answers)
Closed 9 years ago.
I have created a table and with a primary key called OrderNo.
However, I want the OrderNo be auto increment as well.
How can I do in the following format?
"ABC201320001", "ABC201320002", "ABC201320003", ............ etc.
Here ABC is My Company Name(Default),
2013 is Current Year,
2 is the age of my Company
and 0001 is the Document No(Running Number)
Here the auto increment(ABC0001,ABC0002,...) is working good... but the problem is how to get current year(2013,..) and age of my company(2,..) increments based on the current year changes to next year.
Is there a way I can do this in SQL Server?
Use an IDENTITY and a computed column
CREATE TABLE Tablename (
ID int NOT NULL IDENTITY (1, 1),
...
...
/*gives 000-999. Change the RIGHT as needed to give more*/
PIC_ID AS 'PIC' + RIGHT('000000000' + CAST(ID as varchar(10)), 3)
CONSTRAINT PK_name PRIMARY KEY CLUSTERED (PIC_ID)
)
You can change the RIGHT to cover as many digits as needed, or you may not want leading zeroes:
PIC_ID AS 'PIC' + CAST(ID as varchar(10))
In your case it would look like this:
create table tablename
(
ID int identity (0000, 1),
PIC_ID as 'PIC'+right('0000'+cast(ID as varchar(5)), 5) persisted,
constraint PK_tablename primary key (ID)
)