the SQLExecute and SQLSelect commands seem to be limited to a single SQL operation.
Is there a easy way to execute a “SQL Script”… ie a string that contains multiple SQL commands.
First thought was … no problem. Split by “;”… but that won’t work because a ; could be in a quoted string, or interior to a CREATE Trigger
Second thought… Parse string, breaking on “;” that was not inside quotes, or between BEGIN / END keywords. but that won’t work because of the complexity of escaping quotes not to mentioni SQLlite not caring about the use of Double Quotes vs Single Quotes… It could be done, but rather complex.
If I’m creating an entire database structure I tend to make a constant and then do a single SQLExecute (with transaction control). I believe that internally, the semi colon is the delimiter for SQL statements and every database I’ve ever worked on figures it out. Doing them all individually is icky.
well I lifted the “alter table” line and put it as the initial value of a text area
altered my code to run “textarea1.text” instead of the original line
still works
guess you’ll have to debug yours to see why as I’ve no additional ideas at this point
I figured it out…
Since I don’t know what kind of SQL statement(s) the user is going to type into the TextArea… I used SQLSelect not SQLExecute, because if there is a need to return a recordset I need it… and for my previous testing it worked fine if it was just one statement. And if the SQL statement was not a SELECT statement it returned a NIL Recordset which was fine
Emile… doesn’t matter what terminal mode does or does not do… thats not the point…
SQLExecute seems to work… but I can’t use that in this situation because sometimes the submitted SQL needs to return a recordset.
As I stated above. SQLSelect given an SQL statement that is NOT a select , executes, and returns a NIL recordset… but it only executes the FIRST statment in the string provided to it.
SQLExecute will execute multiple queries, but cannot return a Recordset
So as an example
Alter table rename a1 to a2;
select * from a2;
there is no way (that I can see to execute that as a script.
SQLSelect would do only the alter table, SQLExecute would not return the required record set.
I used the example project and changed the create table button to create a table named a1 rather than ‘Team’. In the add records button I added the code to alter the table. If the second alter didn’t successfully change the name to ‘Team’ then the insert would fail.
I wonder how Valentina Studio does this. In Valentina I can execute multiple statements and even multiple selects.
The problem with just using SQLExecute on a script is the error routines. I have just tried a large script that I have and added a couple of deliberate errors.
The result is that the errorMessage returned from the routine is the first error it encountered and the rest of the script was not run. In other words the script aborted at the error. Also, it did not rollback.
I appreciate that one should do a rollback and present the first error but, I think, the user should be aware of as much as possible.
In SQLite Control (my free offering) I split the script into the individual statements and SQLExecute each one, trapping the errors as I get so that I can present the user with all the errors encountered. Also, I rollback the whole transaction (the whole script).
As Dave is creating an SQLite manager then I feel that this is the way to go so that the user can play with his script until it runs error free.
For anyone who is interested… I have a class (based on the ideas that both Simon and myself posted above), that seems to work properly… The heart of which is the tokenizer I wrote for the SQLFormatter topic a week or so back.
as a test … I passed it this string
s="update mytable set [my variable] = ';x;y ;z ;' ; CREATE TRIGGER st_tri after UPDATE of "column2" , "column3" ON stress_test begin SELECT * FROM fred ; END ; Alter table fred rename to suzy ;"
and it properly split it into the correct 3 SQL statements
update mytable set [my variable] = ‘;x;y ;z ;’ ;
CREATE TRIGGER st_tri after UPDATE of “column2” , “column3” ON stress_test begin SELECT * FROM fred ; END ;