Is there a way to write prepared statements for SQL in ballerina? or is it a good practice to use the following method for that?
function selectUserQuery(string username) returns sql:ParameterizedQuery => `SELECT * FROM users WHERE user_name=${username}`;
In ballerina sql:ParamerterizedQuery
works as a prepared statement. (this differs a little from other languages as ballerina mandates giving the variable order, when writing the statement itself)
Yes, using functions is the best practise to keep SQL statements in ballerina.
For the sake of completeness, I would like to quote the following from this article.
Consider the below statement,
sql:ParameterizedQuery selectQuery = `SELECT * FROM users WHERE user_name=${username}`;
Ballerina executes this query in multiple steps,
Template the query:
The sql module will replace the insertions in the query using ?
. (e.g. `SELECT * FROM users where user_name=?`
) Here, all insertions in the query are considered to be user inputs.
The database compiles the query:
The database validates the templated SQL query for syntax and semantics (column availability, authorization) errors. Finally, the server parses the query.
Placeholder replacement:
The programme sends all the user data values to the database. The database will replace the placeholders at this point. However, since the query is pre-compiled, even if the database appends the values, the scope of the execution will not change. i.e. SQL Injection cannot turn a SELECT
command into a DELETE
.
Query execution.