Return deleted rows in sqlite - sql

It's not efficient to do two queries like SELECT * FROM TABLE WHERE clause and then DELETE * FROM TABLE WHERE clause.
So I want to make DELETE query and return deleted rows (one query).
I tried to do:
DELETE OUTPUT DELETED.*
FROM table
WHERE clause
But I have an error:
SQLite exception: near "OUTPUT": syntax error
How to make it correctly or maybe there is another alternative way to return deleted rows?

The DELETE statement has no OUTPUT clause.
After doing the SELECT, all the important data is in the cache, so the DELETE will run quickly.
And because SELECT plus DELETE is the only way, it is the most efficient way.
Since version 3.35, SQLite has the RETURNING clause.

You can return the records deleted with the returning clause
delete from myTable returning *

You can use the changes() call right after your DELETE query: https://www.sqlite.org/c3ref/changes.html
Implementation will vary depending on the language you're using. For example in PHP you could write:
$sqlite = new SQLite3('database.sqlite');
$statement = $sqlite->prepare('DELETE FROM mytable WHERE myclause');
$statement->execute();
echo $sqlite->changes();

Related

DB2 Error Code -495 while we try deleting records counts more than 400k

We have following query to get the records deleted on fk_data_table, and been found we weren’t able to, as because of 400k records.
Delete FROM BOM_LINK WHERE TEST_OBJECT_OID IN (SELECT DISTINCT
TESTOBJECT_OID FROM TESTOBJECT WHERE TESTOBJECT.TESTOBJECTTYPE_OID =
3);
DB2 Error Code -495 https://www.sqlerror.de/db2_sql_error_-495_sqlstate_57051.html
I think what we can do is,
We can write a function or procedure
We can retrieve data by writing query by SELECT and CURSOR options, instead directly deleting
While iterating CURSOR we can try deleting it. (I am not sure that in this way we can delete the row, anyway lets find this out)
We can do periodical commit, instead of doing commit after extensive amount of deletion.
Could someone help us sorting out this issue which we are facing. Pointing to some SQL code snippets will help us a lot.
Unfortunately, Db2 for Z/OS doesn't allow to delete from a subselect.
I don't have Db2 for Z/OS at hand to check, but you may try the following:
CREATE VIEW BOM_LINK_V AS
SELECT *
FROM BOM_LINK B
WHERE EXISTS
(
SELECT 1
FROM TESTOBJECT T
WHERE T.TESTOBJECT_OID = B.TEST_OBJECT_OID
AND T.TESTOBJECTTYPE_OID = 3
)
FETCH FIRST 1000 ROWS ONLY;
Run DELETE FROM BOM_LINK_V until you get SQLSTATE = '02000' (no rows affected).
Update:
The DELETE statement since v12 supports the FETCH FIRST clause.
So, you may run the following without creating a view until you get SQLSTATE = '02000':
DELETE FROM BOM_LINK B
WHERE EXISTS
(
SELECT 1
FROM TESTOBJECT T
WHERE T.TESTOBJECT_OID = B.TEST_OBJECT_OID
AND T.TESTOBJECTTYPE_OID = 3
)
FETCH FIRST 1000 ROWS ONLY;

SQL server: difference between DELETE <Table> and DELETE from <Table>

SQL server:
Difference between :
Delete tblxyz where id=6
and :
Delete from tblxyz where id=6
Is their any difference between above queries ?
There is no difference if you see the execution plan both generates delete scripts as below
DELETE [testtable] WHERE [numbers]=#1
There is no direct difference between the two statements
(except that I find the "DELETE FROM" easier to read and understand)
note that ANSI does require the "FROM" keyword as stated by jarlh
see also
https://msdn.microsoft.com/en-us/library/ms189835.aspx
There is no difference in your delete.
However, the FROM clause is a fully functional from clause, so you can use it with JOIN. For instance:
delete t
from t join
(select min(id) as minid
from t
group by grp
) tt
on t.id = tt.minid;
This would delete the record with the minimum id for each grp value. The alias after the delete is needed to specify which table to delete from (although in this case, deleting from an aggregation result is not allowed).
Note: This query is for illustrative purposes. There is nothing wrong with the query, but it is not how I would actually write such a query in SQL Server.
According to the MSDN the word "from" is optional. The default is not to use:
FROM
and the target table_or_view_name, or rowset_function_limited.An optional keyword that can be used between the DELETE keyword
However in MS Access (or may be some other databases) you may delete a row using delete * command, so you have to use from:
delete * from phoneBook where....
The from Clause is optional..Below is stripped down version of Syntax..
DELETE
[ TOP ( expression ) [ PERCENT ] ]
[ FROM ]
{ { table_alias
FROM
An optional keyword that can be used between the DELETE keyword and the target table_or_view_name, or rowset_function_limited.

Why does DELETE FROM ... FROM ... not error out?

This bit within a stored proc is apparently valid sql:
DELETE TOP (#MaxRecords)
FROM Table
FROM Table B
INNER JOIN Table2 R ON B.fk = R.pk
WHERE R.Value < #DecVariable;
How can two FROM statements be put together and yet still be valid?
First of all TOP in delete syntax indicates that it is SQL Server.
It is perfect valid query, see DELETE:
FROM
An optional keyword that can be used between the DELETE keyword and the target table_or_view_name, or rowset_function_limited.
FROM table_source
Specifies an additional FROM clause. This Transact-SQL extension to DELETE allows specifying data from and deleting the
corresponding rows from the table in the first FROM clause.
This extension, specifying a join, can be used instead of a subquery in the WHERE clause to identify rows to be removed.
DELETE:
Object:

Update multiple values in an oracle table using values from an APEX collection

I am using APEX collections to store some values and pass them between pages in Oracle Application Express 4.2.3.
I would like to then perform an update statement on a table called "project" with the values from the collection.
My code so far is as follows:
update project
SET name=c.c002,
description=c.c007,
start_date=c.c004,
timeframe=c.c005,
status=c.c009
FROM
apex_collections c
WHERE
c.collection_name = 'PROJECT_DETAILS_COLLECTION'
and id = :p14_id;
where :p14_id is the value of a page item.
However, I am getting the following error:
ORA-00933: SQL command not properly ended
Anyone have any idea on how to approach this?
Thanks!
The UPDATE syntax you are using is not valid in Oracle; it does not allow you to use FROM in the way you are attempting.
The simplest way to do this in Oracle would with a subquery:
update project
set (name, description, start_date, timeframe, status) =
(select c.c002, c.c007, c.c004, c.c005, c.c009
FROM
apex_collections c
WHERE
c.collection_name = 'PROJECT_DETAILS_COLLECTION'
)
WHERE
id = :p14_id
;
Note that if the subquery returns no rows, the columns in the target table will be updated to NULL; this could be avoided by adding a similar EXISTS condition in the predicate for the update. It could also be avoided by using a MERGE statement instead of an UPDATE.
If the subquery returns multiple rows, the statement will throw an error. It looks like tthat should not be the case here.

How to write a update SQL using a select SQL

I want to write a update SQL statement, but one conidtion of this statement is the result from a select SQL statement, and I also want to return the result of the select SQL statement.
Like this: update ... set ... where id = (select id from ...)
I want to return the value of id back.
Does anybody know how should I do this?
Thanks in advance!
I don't believe that's possible in one statement. Update then query (select) the new value, or query the value first, and then submit an update.
Alternative would be a stored procedure on the database, which executes the multiple queries and returns the result for you.
This is not possible in all Java database frameworks that I know. Probably you need to separate your query and update in Java.
I don't see any problem in using a subselect in a WHERE clause of an update statement.
For the second request, getting back the value of id, I know this is possible in DB2, and maybe others implement that syntax too:
SELECT id FROM FINAL TABLE (
update ... set ... where id = (select id from ...)
)
This works also for INSERT and DELETE statements. (See the documentation.)
Update statements won't return the updated datasets. The select in that case would be a subselect that isn't directly accessible.
You'd thus have to use at least two queries:
select the ids you want
call the update query passing the previously selected ids as a parameter