SQLite has a built in function to prevent violating the constraints.
ON CONFLICT
Build a unique constraint on the fields Date
and User
and you can insert the new values with
insert or ignore into TEMP2 ( Date, User )
select Date, User from TEMP1
But it seems that SQLite did not get the uniqueness if one of the fields contains the NULL
value.
To check if the the target table contains the values (containing NULL
or not) you have to
SELECT *
FROM TEMP2
WHERE
COALESCE( "DATE", '0000-00-00 00:00:00' ) = COALESCE( :DATE, '0000-00-00 00:00:00' )
AND
COALESCE( "USER", '' ) = COALESCE( :USER, '' )
UPDATE
Your approach will not work, because you only check the current row from TEMP1
but insert all rows from it into TEMP2
.
procedure TForm1.Button1Click(Sender: TObject);
begin
// Prepare the queries
// check duplicates query
UNIQuery1.Close;
UNIQuery1.SQL.Text := 'SELECT * FROM TEMP2 WHERE COALESCE( "DATE", '0000-00-00 00:00:00' ) = COALESCE( :DATE, '0000-00-00 00:00:00' ) AND COALESCE( "USER", '' ) = COALESCE( :USER, '' )';
// insert data query
UNIQuery2.Close;
UNIQuery2.SQL.Text := 'INSERT INTO TEMP2 (DATE,USER) VALUES (:DATE,:USER)';
// walk through TEMP1
UNITable1.First;
while not UNITable1.EOF do
begin
// check current row of TEMP1 for duplicates
UNIQuery1.Params.ParamByName('DATE').Value := UNITable1.FieldByName('DATE').Value;
UNIQuery1.Params.ParamByName('USER').Value := UNITable1.FieldByName('USER').Value;
UNIQuery1.Open;
// if no duplicates found
if UNIQuery1.IsEmpty then
begin
// insert the data
UNIQuery2.Params.ParamByName('DATE').Value := UNITable1.FieldByName('DATE').Value;
UNIQuery2.Params.ParamByName('USER').Value := UNITable1.FieldByName('USER').Value;
UNIQuery2.ExecSQL;
// delete current entry from TEMP1
UNITable1.Delete;
end
else
// next row from TEMP1
UNITable1.Next;
end;
// refresh
UNITable1.Refresh;
UNITable2.Refresh;
end;
But for this you have to be careful in multi-user-scenarios. Someone can insert the same data in the small time gap between checking this soft constraint and inserting the data.
And this are hard to find failures