SQLite check for duplicate rows - sqlite

I have an SQLite database for an art exhibition. In the table "exhibits" I have columns for the artwork ID, the exhibition space ID, a begin date, and an end date. The default value for "end date" is NULL.
Of course, the same artwork cannot be displayed in two different spaces at once. So I want to ensure that a new row with an artwork ID is not created unless all existing rows with that same artwork ID have a non-null end date.
Is there some kind of constraint, trigger, etc. that I can add to the table to ensure this?

I am not an expert on writing triggers for SQLite but something like this should work,
CREATE TRIGGER check_open_ended_exhibit BEFORE INSERT ON exhibits
BEGIN
SELECT RAISE(ABORT, "Open ended exhibit exists")
WHERE EXISTS(SELECT * FROM exhibits WHERE artworkID = NEW.artworkID AND enddate IS NULL);
END

According to your information “Artwork” cannot be displayed twice in the same show which means the EndTime is a unique field when constraining it together with Artwork. So by making these two together your constrain you won’t be able to insert a record if you already have “artwork and NULL”.
So yeah you can just create a unique constrain on these two columns.
CREATE TABLE testConstrain (
id INTEGER NOT NULL,
endDate DATETIME
)
CREATE UNIQUE INDEX testConstrain
ON testConstrain(id, endDate);
INSERT INTO testConstrain VALUES('1',null)
INSERT INTO testConstrain VALUES('2','01-01-2018')
INSERT INTO testConstrain VALUES('1','01-01-2018')
INSERT INTO testConstrain VALUES('1',null)
`
And you will get:
Started executing query at Line 11
(1 row affected)
(1 row affected)
(1 row affected)
Msg 2601, Level 14, State 1, Line 4
Cannot insert duplicate key row in object 'bginsburg.testConstrain' with unique index 'testConstrain'. The duplicate key value is (1, ).
The statement has been terminated.

Related

Inserting rows from table2 to end of table1 with unique ids

I'm trying to add a test user to my website that employers can look at to see my work. I want to use some of the data I have entered into my profile so that it is faster.
I have a workouts table:
CREATE TABLE workouts(
id INTEGER NOT NULL,
userID INTEGER NOT NULL,
DateAndTime smalldatetime NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (UserID) REFERENCES users(id)
);
I have taken 25 of the first results and put it into a temporary workouts2 table:
CREATE TABLE workouts2 (
userid integer,
dateandtime smalldatetime);
Now I want to take those rows from workouts2 and put them into workouts. I have tried to add them by inserting workouts2 into workouts like this:
insert into workouts (id , userID, DateandTime) values (select * from workouts2);
This gives me an Error: in prepare, near "select": syntax error (1)
I can do it one at a time like this:
insert into workouts (userid, dateandtime) values (2, "2022-01-02T06:00");
Doing it one at a time is not ideal.
What am I missing here? I know I have a syntax error but I don't know how to fix it.
I have looked at this question which inserts one at a time:
How to insert a unique ID into each SQLite row?
The problem is it only inserts one at a time.
You should use SELECT instead of VALUES and not include the column id, which is auto-incremented, in the list of columns of workouts which will receive the values (such a column does not exist in workouts2):
INSERT INTO workouts (userID, DateandTime)
SELECT *
FROM workouts2;

To INSERT a row into table from another table

I have the 'SchoolYearTeachingDays' table with just one column, in which are dates:
CREATE TABLE SchoolYearTeachingDays (
aDate DATE PRIMARY KEY
UNIQUE
);
I filled it with many dates which are unique. These dates excludes dates for Sundays and for Saturdays.
I have another, the 'TeachingSaturdaysInSchoolYear' table:
CREATE TABLE TeachingSaturdaysInSchoolYear (
id INT PRIMARY KEY
UNIQUE,
aDate DATE,
TimetableForTheDay TEXT
);
This table holds just two dates. These two dates are for two Saturdays. On these two Saturdays we have to teach students.
When I do the following query on this table, I get these two records:
2018-04-14
2018-05-05
I want to INSERT these two dates from the 'TeachingSaturdaysInSchoolYear' table into 'SchoolYearTeachingDays' table.
I am trying with this query:
INSERT INTO SchoolYearTeachingDays
SELECT aDate FROM TeachingSaturdaysInSchoolYear
;
but I get this error:
Error: UNIQUE constraint failed: SchoolYearTeachingDays.aDate
How this query of mine works and why I get this error? How do I accomplish my goal?
Best, Pal
You are violating unique constraint by inserting duplicate values into the table SchoolYearTeachingDays.
To fix the error put a not in condition so that dates which are already inserted won't get inserted again into SchoolYearTeachingDays table.
Example,
INSERT INTO SchoolYearTeachingDays
SELECT aDate FROM TeachingSaturdaysInSchoolYear T WHERE T.aDate NOT IN (SELECT S.aDate FROM SchoolYearTeachingDays S)

Insert/update trigger updating column value of all rows

I am running into a logical problem.My Trigger is:
create trigger Points1
on Posts
after insert, update
As
declare #value int
declare #postedby int
select #value= Count(Message) from Posts
select #postedby = PostedBy from Posts
update AspNetUsers set User_points = #value * 3
where ( AspNetUsers.Id = #postedby)
I dont know whether i am doing it right or not.
Two tables: AspNetUsers table with User_points column and Id Column as primary key
Posts table with PostId as primary key and PostedBy as foreign key referencing the AspNetUsers table.
Now, i want to compare PostedBy with Id column and if they both are same then update the User_Points column with +3 on every single message he posted.
Now, problem is:
1> It is inserting same number of points in every Row.It should check only currently inserted row and the PostedBy column of that row and then compare with Id column of other table and should Update user's Point of only that Id.
But same result nothing happens
Please tell me how to do it.
thanks in advance
change
select #postedby = PostedBy from Posts
to
select #postedby = PostedBy from INSERTED
'INSERTED' is a magic table that keep insert/updated data in this scope.
Same as this 'DELETED' table keep previous data in update a row

SQLite3 increment partial key sequence

I'm trying to create an incrementing column in SQLite to keep information in the order it exists in an imported text log and grouped by item.
CREATE TABLE log (
row INTEGER PRIMARY KEY AUTOINCREMENT,
item TEXT,
info TEXT
);
Using the following table, I'd like to automatically increment "seq" relative to "item".
CREATE TABLE test (
item TEXT,
seq INTEGER,
info TEXT,
CONSTRAINT pk_test PRIMARY KEY (item, seq)
);
I've tried various INSERTs and continually get UNIQUE/CONSTRAINT violations:
INSERT INTO test (item, seq, info)
SELECT item, (SELECT count(item) FROM test t WHERE l.item=t.item) + 1, info
FROM log l;
INSERT INTO test (item, seq, info)
SELECT item, (SELECT COALESCE(MAX(seq),0)+1 FROM test t WHERE l.item=t.item), info
FROM log l;
When I remove the CONSTRAINT to see the results, "seq" always ends up 1.
The problem is that you're counting rows with the same item value in the test table, but that table is not yet filled.
Just count rows in the log table instead.
Because you see all rows, but want only previous rows, you must add another filter (if you don't have something like a timestamp, use the rowid):
..., (SELECT COUNT(*)
FROM log AS l2
WHERE l2.item = l.item
AND l2.rowid <= l.rowid)), ...

"Insert if not exists" statement in SQLite

I have an SQLite database. I am trying to insert values (users_id, lessoninfo_id) in table bookmarks, only if both do not exist before in a row.
INSERT INTO bookmarks(users_id,lessoninfo_id)
VALUES(
(SELECT _id FROM Users WHERE User='"+$('#user_lesson').html()+"'),
(SELECT _id FROM lessoninfo
WHERE Lesson="+lesson_no+" AND cast(starttime AS int)="+Math.floor(result_set.rows.item(markerCount-1).starttime)+")
WHERE NOT EXISTS (
SELECT users_id,lessoninfo_id from bookmarks
WHERE users_id=(SELECT _id FROM Users
WHERE User='"+$('#user_lesson').html()+"') AND lessoninfo_id=(
SELECT _id FROM lessoninfo
WHERE Lesson="+lesson_no+")))
This gives an error saying:
db error near where syntax.
If you never want to have duplicates, you should declare this as a table constraint:
CREATE TABLE bookmarks(
users_id INTEGER,
lessoninfo_id INTEGER,
UNIQUE(users_id, lessoninfo_id)
);
(A primary key over both columns would have the same effect.)
It is then possible to tell the database that you want to silently ignore records that would violate such a constraint:
INSERT OR IGNORE INTO bookmarks(users_id, lessoninfo_id) VALUES(123, 456)
If you have a table called memos that has two columns id and text you should be able to do like this:
INSERT INTO memos(id,text)
SELECT 5, 'text to insert'
WHERE NOT EXISTS(SELECT 1 FROM memos WHERE id = 5 AND text = 'text to insert');
If a record already contains a row where text is equal to 'text to insert' and id is equal to 5, then the insert operation will be ignored.
I don't know if this will work for your particular query, but perhaps it give you a hint on how to proceed.
I would advice that you instead design your table so that no duplicates are allowed as explained in #CLs answer below.
For a unique column, use this:
INSERT OR REPLACE INTO tableName (...) values(...);
For more information, see: sqlite.org/lang_insert
insert into bookmarks (users_id, lessoninfo_id)
select 1, 167
EXCEPT
select user_id, lessoninfo_id
from bookmarks
where user_id=1
and lessoninfo_id=167;
This is the fastest way.
For some other SQL engines, you can use a Dummy table containing 1 record.
e.g:
select 1, 167 from ONE_RECORD_DUMMY_TABLE

Resources