3

I want to display a query without executing it using the Query Builder. I want to write something like:

\DB::table('my_table')-> updateOrInsert(['a' => 'b'], ['c' => 'd']);

It's a production action so I am a bit stressed about running it directly. Is there any way to display it instead of running it?

0

3 Answers 3

9

If you have a query builder instance you can use toSql(). Since the updateOrInsert() method does not return an builder instance you can't prevent its execution that way. Instead you can put the query inside a DB::pretend() closure and it should return the query it would execute.

\DB::pretend(function() {
    \DB::table('my_table')->update(['a' => 'b']);
});

Should return:

[
    [
        "query" => "update `my_table` set `a` = ?",
        "bindings" => [
            "b",
        ],
        "time" => 0.01,
    ],
]

Note: the example you provided will never work because insertOrUpdate() does not exist. I believe you're looking for updateOrInsert()

Sign up to request clarification or add additional context in comments.

Comments

0

After investigating the class at:

vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php

You can do the following to generate insert SQL without running them:

use Illuminate\Support\Facades\DB;

function insertRawSql(string $table, array $values): string
{
    $builder = DB::table($table);
    return $builder->grammar->substituteBindingsIntoRawSql(
        $builder->grammar->compileInsert($builder, $values),
        $builder->cleanBindings($builder->connection->prepareBindings($values))
    );
}

echo insertRawSql('mytable', ['id' => 123, 'name' => 'Test', 'date' => \Carbon\Carbon::now()]);

Give:

insert into "mytable" ("id", "name", "date") values (123, 'Test', '2025-10-24 17:11:00.643')

You just need a connection to a database (sqlite, postgresql, mysql, ...) because of $builder->connection call, but it doesn't run any request so the table may not exist.

Same is possible for update() query.

Comments

-1

You can see raw queries with:

$foo = DB::getQueryLog();
var_dump($foo);

It will execute the queries.

4 Comments

I don't believe that's possible. A good tutorial is available here: scotch.io/tutorials/debugging-queries-in-laravel
@Gab It is possible. See my answer.
"It will execute the queries." OP has explicitly stated, that they don't want that.
I just want to thank you for this timely feedback, 8 years, 7 months, and 12 days after I answered OPs question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.