I know I can use the toSql
method on a query builder to get the raw SQL with binding parameter placeholders for a SELECT
statement.
App\User::where(['id'=>'1'])->toSql();
"select * from `users` where (`id` = ?)"
But how can I get this for a DELETE
statement?
App\User::where(['id'=>'1'])->delete()->toSql();
PHP error: Call to a member function toSql() on integer on line 1
This executes the statement, but I would like to get the raw, uninterpolated SQL generated with the question marks standing in for values without actually running the query. The same case holds for any modification statement, such as INSERT
or UPDATE
This smells a lot like an xy problem. My web application includes a multi-process architecture. It runs custom artisan commands with asynchronous communication listening in an event-driven loop that update the database.
The reason I need the raw query is because I want to reuse a prepared statement for performance efficiency. Unfortunately, the eloquent methods do not expose the prepared statement, so in order to reuse one, I'll have to prepare it myself from the underlying PDO connection.
$sql = 'UPDATE `foo` SET `bar` = ? WHERE (`id` = ?)';
$statement = DB::connection()->getPdo()->prepare($sql);
while (true) {
$data = foo();
$statement->execute([$data->bar, $data->id]);
}
However, this departs from the abstracted SQL grammar builder. Because I'm using MySQL at the moment, I can syntactically include the backticks. But now I'm stuck with vendor lock-in. Say for example, the boss says we're moving to MS SQL Server tomorrow, then it's likely going to be annoying (at least) to have to catch bugs for using backticks instead of square braces.
I want to use the dynamically generated SQL grammar for reusing in a prepared statement.
DB::raw() is used to make arbitrary SQL commands which aren't parsed any further by the query builder. They therefore can create a vector for attack via SQL injection.
DB::QueryLog() works only after you execute the query using $builder->get() . If you want to get the raw query before or without executing the query, you can use the $builder->toSql() method.
Raw SQL queries are useful if the query you want can't be expressed using LINQ. Raw SQL queries are also used if using a LINQ query is resulting in an inefficient SQL query. Raw SQL queries can return regular entity types or keyless entity types that are part of your model.
First get a query builder instance for the model's table.
$builder = DB::table((new User)->getTable());
Then get the grammar and compile the delete statement from the builder with a where clause.
$sql = $builder->getGrammar()->compileDelete($builder->where('id', 1));
"delete from `users` where `id` = ?"
Now you can freely swap out database drivers and still get the appropriate platform syntax.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With