Using values or variables more than once in stored procedures using MySQL.
In Xojo I find myself binding variables multiple times because in Xojo the binding is numbered rather than named.
Consequently, when using the same variable in a query more than once I need to bind it more than once.
This is what I do today all the time.
Am I overlooking something? Is there, for example, an internal notation documented somewhere like @1, @2 that can be used creating prepare the SQL?
Don’t use BIND, just list them in the EXECUTE statement
stmt = SQLitePreparedStatement(db.Prepare("SELECT * FROM Customers WHERE FirstName like ? "))
stmt.BindType(0, SQLitePreparedStatement.SQLITE_TEXT)
stmt.Bind(0, TextField1.Text)
rs=stmt.SQLSelect
or this instead?
stmt = SQLitePreparedStatement(db.Prepare("SELECT * FROM Customers WHERE FirstName like ? "))
stmt.BindType(0, SQLitePreparedStatement.SQLITE_TEXT)
rs=stmt.SQLSelect(textfield1.text)
rs=stmt.SQLSelect("someothertext")
I mean the ‘?’ being used several times. I know how to do it with an INSERT ON DUPLICATE KEY UPDATE.
INSERT INTO some_table (example) VALUE(?) ON DUPLICATE KEY UPDATE example = VALUES(example). In this, value naming is linked via the column name. In multi-level queries that is not possible.
Some times in multi-level queries the same ‘?’ needs to be used. But there is no link to a named variable. In other languages, you can declare a sql variable and then use it more than it once in the query.
db.Prepare("SELECT * FROM tableName WHERE id LIKE ? OR parentID LIKE ? ")
With the ability to just bind once instead of setting up a bind statement for each position since those replacement values are expected to be identical (in this case, if row’s id field matches the value, or is a child of the row whose id field matches the value).
You could write a method to parse the SQL statement using predefined key/value pairs to setup the bindings for you. Would save you a lot of work in the end if you’re doing this often.
Here’s an example to help you along. Not necessarily the best method, but it will get you started.
Add this method to a module:
[code]Public Function KeyPrepare(extends db as Database, SQLStatement as String, Values as Dictionary) as String
dim returnString as String = SQLStatement
dim keyString as String
dim valueString as String
for intCycle as Integer = 0 to Values.Count - 1
keyString = values.Key(intCycle).StringValue
valueString = values.Value(keyString).StringValue
dim dValues as new Dictionary( "id" : 1 )
rs = db.SQLSelect( db.KeyPrepare( "SELECT * FROM tableName WHERE id LIKE {id} OR parentID LIKE {id}", dValues ) )
Yes, there are certain issues you may need to handle as you encounter them. Hence the “Not necessarily the best method.” Such as escaping quotes. I welcome improvements, but this isn’t meant to be production code, just an example to show how to get started.