SQLite Forum

Are there any plans / chances of supporting a RETURNING clause?
Login
I'm not sure there is much utility in the low-level code, using prepare-step-reset-etc.

The real utility for this comes in the high-level application code where you have abstracted calls to handle the above for you, much in the way that "sqlite3_execute()" does, or when working through a wrapper.

Here are a couple of typical examples with explicit utility:

```
exec("CREATE TABLE t(a INTEGER PRIMARY KEY, b TEXT);");
exec("INSERT INTO t(b) VALUES
 ('Johnny')
,('Joan')
,('Jane')
,('Jimmy')
;");
```
Now there is no way for me this high-level to know what the PK is for those inserted values unless I do those all one-by-one and get the LAST_INSERT_ROWID every time.
A simple change like this:

```
query("INSERT INTO t(b) VALUES
 ('Johnny')
,('Joan')
,('Jane')
,('Jimmy')
RETURNING a,b
;")

```
would do the inserts and instantly give me a result like this:

```
1,Johnny
2,Joan
3,Jane
4,Jimmy
```
which can be parsed in my high-level side to know exactly what was inserted with which ID.

In that example the "inserted" seems obvious, those are the ones I asked for, but in the next example it is less obvious:

```
query("UPDATE t SET b = 'Mr. ' || b
 WHERE b LIKE '%y'
 RETURNING a,b

will return:
a, b
1, Mr. Johnny
4, Mr. Jimmy
```
which again in the high-level parser will be extremely helpful in gaining easy access to feedback to a user (or programmer) what was updated - maybe even to construct a next query based on what was changed, if any.

I propose that the reason you do not find lots of application in current works for this RETURNING model, is merely because it did not exist yet and any possible use of it was handled another way - and perhaps you mainly use the low-level API and never have to work through a wrapper. Add it and application will arise (especially in higher-level code).

Last example:

```
query("DELETE from t WHERE a > 3 RETURNING b");

will return
b
Jane
Jimmy
```
This obviates the need for a pre-query to see what will be affected, then a delete query to affect it, then a post-select query to see if all was indeed deleted as expected, and obviates the need for doing a transaction for all of this. One statement (a transaction unto itself) that executes the idea, and returns the result.

On the high-level side of the programming spectrum, perhaps working through a wrapper (which I know is not something you folks ever do), this kind of construct is an invaluable time-saver and code-quantity-saver. And less code means less opportunity for error and less debugging (as Richard always points out when advocating doing stuff in SQL rather than in code).

Thank you for listening!