phplaravellaravel-query-builder

Get Raw SQL of Insert Statement


I am looking for a way to get the correct SQL queries for an INSERT statement. I'm having to export this data for use in another (non-laravel) system. The post at How to get the raw SQL for a Laravel delete/update/insert statement? got me part of the way there but my queries are still parameterized:

Post::all()->each(function($post)
{
    $builder = DB::table('posts');
    $insertStatement = $builder->getGrammar()->compileInsert($builder->select(['created_at', 'title']), [
                'created_at' => $post->created_at,
                'title' => $post->title
            ]);
    Storage::disk('sql')->append('posts-latest.sql', $insertStatement);
    dump($insertStatement);
}

this results in...

insert into `posts` (`created_at`, `title`) values (?, ?)

So I've managed to set the fields to be updated but how to swap out the parameters for real values?


Solution

  • I ended up discovering DB::pretend which will generate the query without running it. Then it's a case of substitution. It seems that there is no way to get the raw SQL without substitution due to the use of parameters.

    Post::all()->each(function($post)
    {
        $builder = DB::table('posts');
    
        $query = DB::pretend(function() use ($builder, $post)
        {
            return $builder->insert([
                'created_at' => $post->created_at,
                'title' => $post->title,
                'content' => $post->content,
                'featured_image_link' => $post->featured_image_link,
                'slug' => $post->slug
            ]);
        });
        
        $bindings = [];
        collect($query[0]['bindings'])->each(function($binding) use (&$bindings)
        {
            $binding = str_replace("'", "\\'", $binding);
            $bindings[] = "'$binding'";
        });
    
        $insertStatement = Str::replaceArray('?', $bindings, $query[0]['query']);
    
        Storage::disk('sql')->append('posts-latest.sql', $insertStatement.';');
    });