How to know last id of SQLite database [duplicate] - sqlite

This question already has answers here:
Predict next auto-inserted row id (SQLite)
(11 answers)
Closed 6 years ago.
I have a database in SQLite that I'll be using to store restaurants information for a website.
The website will allow users to insert new restaurants in the dabase (through php).
My question is, given that each row in a table in the database has its id attribute (which is the primary key), how can I know what id should the next item I'm going to store in the database have?
If the last item added to the database has the id 50, then the next restaurant a user tries to add should have the id 51, but how can I have access to this?
Here's my SQLite Restaurant table:
CREATE TABLE Restaurant (
id NUMBER PRIMARY KEY NOT NULL,
name NVARCHAR2(20) NOT NULL,
description NVARCHAR2(20),
address NVARCHAR2(20) NOT NULL,
priceRange NUMBER NOT NULL REFERENCES PriceRange(id) ON DELETE SET NULL ON UPDATE CASCADE
);
Thanks in advance!

Since you've tagged the question with php, you should be able to use SQLite3::lastInsertRowID().
Alternatively, a pure SQLite solution is the last_insert_rowid() function.

Related

Simple database structure to link subjects and exam boards

I'm new to Sql and want to use sqlite to create a database to store data about which topics are needed by which exam boards.
So far I've created two tables - one called board and one called topic. I'm not sure how I should represent the relationship between boards and topics. I have read a bit about Normal Form, and I'm pretty sure that I shouldn't be putting multiple entries into one field, and also that having fields like topic1, topic2 etc. is not the way to go.
My sql so far is below. Could someone please help me with the next step - how to make this database actually work for my requirements while not breaking every rule in the book?
For example, I'd like to be able to quickly find out which boards require knowledge of set theory or reciprocal functions etc.
Thanks in advance.
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "topic" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"topic_name" TEXT NOT NULL,
"level" INTEGER
);
CREATE TABLE IF NOT EXISTS "board" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"board_name" TEXT NOT NULL UNIQUE,
"link_to_syllabus" TEXT
);
INSERT INTO "topic" ("id","topic_name","level") VALUES (1,'Pythagoras'' Theorem','F');
INSERT INTO "topic" ("id","topic_name","level") VALUES (2,'Circle theorems','H');
INSERT INTO "topic" ("id","topic_name","level") VALUES (3,'',NULL);
INSERT INTO "board" ("id","board_name","link_to_syllabus") VALUES (0,'Edexcel','https://qualifications.pearson.com/en/qualifications/edexcel-gcses/mathematics-2015.html');
INSERT INTO "board" ("id","board_name","link_to_syllabus") VALUES (1,'OCR','https://www.ocr.org.uk/qualifications/gcse/mathematics-j560-from-2015/');
COMMIT;
If I understood, a board can have one or more topic, and a topic can be in one or more boards. If it is correct, you are searching for a many to many relationship, wich is obtained with the table:
CREATE TABLE board_topic (
board_id INTEGER NOT NULL
REFERENCES topic (id),
topic_id INTEGER NOT NULL
REFERENCES board (id),
CONSTRAINT pk PRIMARY KEY (
board_id ,
topic_id
)
)
About the query you asked for, after you insert some data into the association table just showed, the query looks like:
SELECT board.id, board_name FROM board
JOIN board_topic ON board.id = board_topic.board_id
JOIN topic ON topic.id = board_topic.topic_id
WHERE topic_name = "Circle theorems";

Conditionally add columns in SQLite

I've seen enough answers to know you can't easily check for columns in SQLITE before adding. I'm trying to make a lazy person's node in Node-Red where you pass a message to SQLITE which is the query. Adding a table if it does not exist is easy.
msg.topic='create table IF NOT EXISTS fred (id PRIMARY KEY);'; node.send(msg);
it occurred to me that adding a table which had the names of the fields would be easy - and if the field name is not in the table.... then add the field. BUT you can't add multiple fields at once - so I can't do this...
msg.topic='create table IF NOT EXISTS fred (id PRIMARY KEY, myfields TEXT);'; node.send(msg);
The problem with THAT is that I can't add this in later, there's no way to check before adding a field it the table exists!
This is what I WANT
msg.topic='create table IF NOT EXISTS fred (id PRIMARY KEY, myfields TEXT);'; node.send(msg);
msg.topic='if not (select address from myfields) alter table fred add column address text';
I just cannot think of any way to do this - any ideas anyone (the idea is that the node-red node would input a table, field and value and if the table didn't exist it would be created, if the field didn't exist it would be created, all before trying to add in the value).
You won't be able to make the ALTER TABLE conditional in the SQL itself. You'll need to handle that from your calling script.
Alternately, simply attempt to add the column to the table and accept failure as an outcome. Assuming the table exists, the only failure reason you could encounter is that the column already exists.
If you'd like to do something more graceful, you can check if the column exists in advance, then conditionally run the SQL from your calling application.

sqlite - how to check if table exists before completing inserts? [duplicate]

This question already has answers here:
How do I check in SQLite whether a table exists?
(30 answers)
Closed 3 years ago.
What is the best SQL for a SQLite database to effectively do:
If Database Table Exists then
- create table
- insert row
- insert row (i.e. for startup data)
end
To check that your table exists or not, you can use:
SELECT * FROM sqlite_master WHERE name ='myTable' and type='table';
You can let Sqlite itself check this out for you:
CREATE TABLE IF NOT EXISTS <table_name> ...;
Follow link for documentation:
https://sqlite.org/lang_createtable.html
Use this code
SELECT name FROM sqlite_master WHERE type='table' AND name='yourTableName';
if returning array count is equal to 1 its means table exist else not exist.

Update 2 tables using Stored Procedure in MySql

This seems like a simple request. But my query in not working and I'm finding conflicting answers on the internet. Is it possible to have UPDATE and INSERT using a Stored Procedure joining 2 tables in MySql?
I have an Asp.net Webforms website. It has 2 tables Individual and Address. Individual table contains data on an individual, i.e. Phone Number, Fax, Email ect.
The address table has all the address information for an individual. They each table has a column of Individual ID which auto increments. (Note: the individualID in Address table is not a primary key, but individualID in the individual table is a primary key.
Anyway, I have a FormView in Asp.net that with a SELECT statement that joins those 2 tables and display the data fine. But updating new information to both tables keeps failing.
My most recent error is : Duplicate entry '0' for key 'PRIMARY'
Is there a way to write an UPDATE statement that joins 2 Tables?? This has to exist right?
It is possible to update multiple tables with a single query -
UPDATE table1
INNER JOIN table2
ON table1.id = table2.table1_id
SET table1.col1 = 'some value', table2.col1 = 'Another value'
WHERE <some where clause>;

Best Practices for updating multiple check boxes on a web form to a database

A sample case scenario - I have a form with one question and multiple answers as checkboxes, so you can choose more than one. Table for storing answers is as below:
QuestionAnswers
(
UserID int,
QuestionID int,
AnswerID int
)
What is the best way of updating those answers to the database using a stored proc? At different jobs I've seen all spectrum, from simply deleting all previous answers and inserting new ones, to passing list of answers to remove and list of answers to add to the stored proc.
In my current project performance and scalability are pretty important, so I'm wondering what's the best way of doing it?
Thanks!
Andrey
If I had a choice of table design, and the following statements are true:
You know the maximum choices count per question/
Each choice is a simple checked/unchecked.
Each answer be classified as correct/wrong rather than marked by some scale. (Like 70% right.)
Then considering performance I would considered the following table instead of the one you presented:
QuestionAnswers
(
UserID int,
QuestionID int,
Choice1 bool,
Choice2 bool,
...
ChoiceMax bool
)
Yes, it is ugly in terms of normalization but that denormalization will buy performance and simplify queries -- just one update/insert for one question. (And I would update first and insert only if affected rows equals to zero.)
Also detecting whether the answer was correct will be also more simple -- with the following table:
QuestionCorrectAnswers
(
QuestionID int,
Choice1 bool,
Choice2 bool,
...
ChoiceMax bool
)
All you need to do is just to lookup for the row in QuestionCorrectAnswers with the same combination of choices as user answered.
If the questions are always the same, then you'd never delete anything - just run an update query on all changed Answers.
Update QuestionAnswers
SET AnswerID = #AnswerID
WHERE UserID = #UserID AND QuestionID = #QuestionID
If for some reason you still need to do some delete/insert - I'd check which QuestionIDs already exist (for the given UserID) so you do a minimum of Delete/Insert.
Updates are just far faster than Delete then Insert, plus you don't make any identity columns skyrocket.
I presume you load the QuestionAnswers from DB upon entering the page, so the user can see which answers he/she gave last time - if you did you already have the necessary data in memory, for determining what to delete, insert and update.
Andrey: If the user (userid=1) selects choices a(answerid=1) & b(answerid=2) for question 1(questionid=1) and later switches to c (a-id=3) & d(a-id=4), you would have to check, then delete the old and add the new. If you choose to follow the other approach, you would not be checking if a particular record exists (so that you can update it), you would just delete old records and insert new records. Anyways, since you are not storing any identity columns, I would go with the latter approach.
It is a simple solution:
Every [Answer] should have integer value (bit) and this value is unique for current Question.
For example, you have Question1 and four predefined answers:
[Answer] [Bit value]
answer1 0x00001
answer2 0x00002
answer3 0x00004
answer4 0x00008
...
So, you SQL INSERT/UPDATE will be:
declare #checkedMask int
set #checkedMask = 0x00009 -- answer 1 and answer 4 are checked
declare #questionId int
set #questionId = 1
-- delete
delete
--select r.*
r
from QuestionResult r
inner join QuestionAnswer a
on r.QuestionId = a.QuestionId and r.AnswerId = a.AnswerId
where r.QuestionId = #questionId
and (a.mask & #checkedMask) = 0
-- insert
insert QuestionResult (AnswerId, QuestionId)
select
AnswerId,
QuestionId
from QuestionAnswer a
where a.QuestionId = #questionId
and (a.mask & #checkedMask) > 0
and not exists(select AnswerId from QuestionResult r
where r.QuestionId = #questionId and r.AnswerId = a.AnswerId)
Sorry to resurect an old thread. I would have thought the only realistic solution is to delete all responses for that question, and create new rows where the checkbox is ticked. Having a column per answer may be efficient as far as updates go, but the inflexibility of this approach is just not an option. You need to be able to add options to a question without having to redesign your database.
Just delete and re-insert. Thats what databases are designed to do, store and retrieve lots of rows of data.
I disagree that regent's answer is denormalized. As long as each answer is not dependent on another column, and is only dependent on the key, it is in 3rd normal form. It is no different than a table with the following fields for a customer name:
CustomerName
(
name_prefix
name_first
name_mi
name_last
name_suffix
city
state
zip
)
Same as
QuestionAnswers
(
Q1answer1
Q1answer2
Q1answerN
)
There really is no difference between the "Question" of name and the multiple answers which may or may not be filled out and the "Question" of the form and the multiple answers that may or may not be selected.

Resources