SQLite and 'returning'

I’m about to create a documentation Issue. This is because the SQLite docs for the SQLiteDatabase, and more particularly ExecuteSQL and SelectSQL, seem to assume that an SQL statement such as CREATE, DELETE, INSERT, or UPDATE would always be done using ExecuteSQL, and SELECT would always be done using SelectSQL, the reason being that while SELECT returns a RowSet, the other statements (DELETE and so on), don’t.

However, I am just starting to use the RETURNING clause (see RETURNING), which for example allows me to delete some rows from a database while at the same time returning some data from those deleted rows. This appears to work as hoped for a statement such as:

Var  dbh as SQLiteDatabase, reg as RowSet

// Assume dbh initialised
reg = dbh.SelectSQL ("delete from mytable where myid=? returning othercol", idvar)
// Process Rowset of othercol values of the deleted rows.

IOW, SelectSQL should be used for anything that may return a RowSet, and ExecuteSQL otherwise.

Can I take this to be the case?

if you use RETURNING you need to use a SelectSQL so you are correct.

The only reason ExecuteSQL and SelectSQL exist is because Xojo can’t override based on return type alone. Otherwise it’d likely be QuerySQL() and QuerySQL() As RowSet. With the normal parameters of course. They both do the same thing, it’s just a matter of whether or not you’re getting a RowSet back.

2 Likes

I’ll get an Issue going, then. Thanks.

https://tracker.xojo.com/xojoinc/xojo/-/issues/75104

Xojo behavior is not equivalent.

I verified that Xojo, using SQLite at least, does the following:

ExecuteSQL executes multiple statements,
SelectSQL execute the first one and ignores the rest.

Perhaps because it can only return one RowSet. What would it do if the second statement also wanted to return rows?

I only use ExecuteSQL for a single statement, so there is no difference for me.

I and the rest of the world not.

But that’s not a problem, because Xojo allows that. The problem is the other way around. SelectSQL.

1 Like

What do you expect back from multiple statements and SelectSQL?

  • The last select result only?
  • The first select result only?
  • Multiple RowSets?

The possible reason it only returns the first SQL statement is the injection protection.

Usually we have multiple rowsets on other languages, but I mostly only care being able to return the last one, before it I may start a transaction, insert something, update something, commit and return something, all at once if I wanted.

But SelectSQL uses a prepared statement and I’m not sure that is compatible with your wishes.

The Xojo SQLExecute allows multiple statements, also uses preparation. Same magic could be applied.

Then it must be splitting them before execution. Also I don’t know how you would bind to a set of sql statements.

Xojo isn’t alone in this. php claims to only support a single statement in select, there are certainly version that ignore that “feature”.