# Base de datos: constructor de consultas (query builder)

# Introducción

El constructor de consultas (query builder) de Base de datos de Laravel, proporciona una interface fluida y conveniente para la creación y ejecución de consultas de bases de datos. Puede ser usado para ejecutar las principales operaciones de bases de datos en tu aplicación y funciona en todos los sistemas de bases de datos soportados.

El constructor de consultas de Laravel usa enlazamiento de parámetros PDO para proteger tu aplicación contra ataques de inyección SQL. No hay necesidad de limpiar cadenas que están siendo pasadas como enlaces.

Nota

PDO no admite nombres de columna de enlace (binding). Por lo tanto, nunca debes permitir que la entrada de usuario dicte los nombres de columna a los que hacen referencia tus consultas, incluidas las columnas "ordenar por", etc. Si debes permitir que el usuario seleccione ciertas columnas para consultar, valida siempre los nombres de las columnas con un una lista blanca de columnas permitidas.

# Obteniendo los resultados

# Obteniendo todas las filas de una tabla

Puedes usar el método table de la clase facade DB para empezar una consulta. El método table devuelve una instancia para construir consultas fáciles de entender para la tabla dada, permitiendo que encadenes más restricciones dentro de la consulta y recibas finalmente los resultados usando el método get:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;

class UserController extends Controller
{
    /**
    * Show a list of all of the application's users.
    *
    * @return Response
    */
    public function index()
    {
        $users = DB::table('users')->get();

        return view('user.index', ['users' => $users]);
    }
}

El método get devuelve una colección de la clase Illuminate\Support\Collection que contiene los resultados donde cada resultado es una instancia del objeto StdClass de PHP. Puedes acceder al valor de cada columna accediendo a la columna como una propiedad del objeto:

foreach ($users as $user) {
    echo $user->name;
}

# Obteniendo una sola fila / columna de una tabla

Si solamente necesitas recuperar una sola fila de la tabla de la base de datos, puedes usar el método first. Este método devolverá un solo objeto StdClass:

$user = DB::table('users')->where('name', 'John')->first();

echo $user->name;

Si no necesitas una fila completa, puedes extraer un solo valor de un registro usando el método value. Este método devolverá directamente el valor de la columna:

$email = DB::table('users')->where('name', 'John')->value('email');

Para obtener una sola fila por su valor de columna id, use el métodofind:

$user = DB::table('users')->find(3);

# Obteniendo una lista de valores de columna

Si prefieres obtener una Colección que contenga los valores de una sola columna, puedes usar el método pluck. En el siguiente ejemplo, obtendrémos una colección de títulos de rol:

$titles = DB::table('roles')->pluck('title');

foreach ($titles as $title) {
    echo $title;
}

También puedes especificar una columna clave personalizada para la colección retornada:

$roles = DB::table('roles')->pluck('title', 'name');

foreach ($roles as $name => $title) {
    echo $title;
}

# Particionando los resultados

Si nececesitas trabajar con miles de registros de bases de datos, considera usar el método chunk. Este método obtiene una partición pequeña de los resultados cada vez y pone cada partición dentro de un Closure para su procesamiento. Este método es muy útil para escribir comandos de Artisan que procesan miles de registros. Por ejemplo, vamos a trabajar con la tabla completa users en particiones de 100 registros cada vez:

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
    foreach ($users as $user) {
        //
    }
});

Puedes parar de obtener particiones para que no sean procesadas al devolver false en el código Closure:

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
    // Process the records...

    return false;
});

Si estás actualizando registros de base de datos mientras particionas resultados, los resultados de particiones podrían cambiar en formas inesperadas. Entonces, cuando se actualicen los registros mientras se particiona, siempre es mejor usar el método chunkById en su lugar. Este método paginará automáticamente los resultados basándose en la llave primaria del registro:

DB::table('users')->where('active', false)
    ->chunkById(100, function ($users) {
        foreach ($users as $user) {
            DB::table('users')
                ->where('id', $user->id)
                ->update(['active' => true]);
        }
    });

Nota

Al actualizar o eliminar registros dentro del callback de la partición, cualquier cambio en la clave primaria o claves foráneas podría afectar a la consulta de la partición. Esto podría potencialmente dar lugar a que los registros no se incluyan en los resultados particionados.

# Agrupamientos

El constructor de consultas también proporciona una variedad de métodos de agrupamiento tales como count, max, min, avg y sum. Puedes ejecutar cualquiera de estos métodos después de construir tu consulta:

$users = DB::table('users')->count();

$price = DB::table('orders')->max('price');

Puedes combinar estos métodos con otras cláusulas:

$price = DB::table('orders')
                ->where('finalized', 1)
                ->avg('price');

# Determinando si existen registros

EN vez de usar el método count para determinar si existen registros que coincidan con los límites de tu consulta, puedes usar los métodos exists y doesntExist:

return DB::table('orders')->where('finalized', 1)->exists();

return DB::table('orders')->where('finalized', 1)->doesntExist();

# Selects

# Especificando una cláusula select

No siempre desearás seleccionar todas las columnas de una tabla de la base de datos. Usando el método select, puedes especificar una cláusula select personalizada para la consulta:

$users = DB::table('users')->select('name', 'email as user_email')->get();

El método distinct te permite forzar la consulta para que devuelva solamente resultados que sean distintos:

$users = DB::table('users')->distinct()->get();

Si ya tienes una instancia del constructor de consultas y deseas añadir una columna a su cláusula select existente, puedes usar el método addSelect:

$query = DB::table('users')->select('name');

$users = $query->addSelect('age')->get();

# Expresiones sin procesar (raw)

Algunas veces puedes necesitar usar una expresión sin procesar en una consulta. Para crear una expresión sin procesar, puedes usar el método DB::raw:

$users = DB::table('users')
                     ->select(DB::raw('count(*) as user_count, status'))
                     ->where('status', '<>', 1)
                     ->groupBy('status')
                     ->get();

Nota

Las instrucciones sin procesar serán inyectadas dentro de la consulta como cadenas, así que deberías ser extremadamente cuidadoso para no crear vulnerabilidades de inyección SQL.

# Métodos Raw

En lugar de usar DB::raw, también puedes usar los siguientes métodos para insertar una expresión sin procesar dentro de varias partes de tu consulta.

# selectRaw

El método selectRaw puede ser usado en lugar de addSelect(DB::raw(...)). Este método acepta un arreglo opcional de enlaces como su segundo argumento:

$orders = DB::table('orders')
                ->selectRaw('price * ? as price_with_tax', [1.0825])
                ->get();

# whereRaw / orWhereRaw

Los métodos whereRaw y orWhereRaw pueden ser usados para inyectar una cláusula where sin procesar dentro de tu consulta. Estos métodos aceptan un arreglo opcional de enlaces como segundo argumento:

$orders = DB::table('orders')
                ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
                ->get();

# havingRaw / orHavingRaw

Los métodos havingRaw y orHavingRaw pueden ser usados para establecer una cadena sin procesar como el valor de la cláusula having:

$orders = DB::table('orders')
                ->select('department', DB::raw('SUM(price) as total_sales'))
                ->groupBy('department')
                ->havingRaw('SUM(price) > 2500')
                ->get();

# orderByRaw

El método orderByRaw puede ser usado para establecer una cadena sin procesar como el valor de la cláusula order by:

$orders = DB::table('orders')
                ->orderByRaw('updated_at - created_at DESC')
                ->get();

# Joins

# Cláusula inner join

El constructor de consultas también puede ser usado para escribir instrucciones joins. Para ejecutar un "inner join" básico, puedes usar el método join en una instancia del constructor de consultas. El primer argumento pasado al método join es el nombre de la tabla que necesitas juntar, mientras que los argumentos restantes especifican las restricciones de columna para el join. Ciertamente, como puedes ver, puedes hacer un join de múltiples tablas en una sola consulta:

$users = DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->get();

# Cláusula left join / right join

Si prefieres ejecutar un "left join" o un "right join" en vez de un "inner join", usa los métodos leftJoin o rightJoin. Estos métodos tienen la misma forma de uso de los argumentos que el método join:

$users = DB::table('users')
            ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
            ->get();

$users = DB::table('users')
            ->rightJoin('posts', 'users.id', '=', 'posts.user_id')
            ->get();

# Cláusula cross join

Para ejecutar un cláusula "cross join" usa el método crossJoin con el nombre de la tabla a la que deseas hacerle un cross join. Los cross join generan un producto cartesiano entre la primera tabla y la tabla juntada:

$users = DB::table('sizes')
            ->crossJoin('colours')
            ->get();

# Cláusulas de join avanzadas

También puedes especificar cláusulas join más avanzadas. Para empezar, pasa una función Closure como el segundo argumento dentro del método join. La Closure recibirá un objeto JoinClause el cual permitirá que especifiques restricciones en la cláusula join:

DB::table('users')
        ->join('contacts', function ($join) {
            $join->on('users.id', '=', 'contacts.user_id')->orOn(...);
        })
        ->get();

Si prefieres usar una cláusula estilo "where" en tus joins, puedes usar los métodos where y orWhere en un join. En lugar de comparar dos columnas, estos métodos compararán la columna contra un valor:

DB::table('users')
        ->join('contacts', function ($join) {
            $join->on('users.id', '=', 'contacts.user_id')
                    ->where('contacts.user_id', '>', 5);
        })
        ->get();

# Subconsultas joins

Puedes utilizar los métodos joinSub, leftJoinSub y rightJoinSub para unir una consulta a una subconsulta. Cada uno de estos métodos recibe tres argumentos: la subconsulta, su alias de tabla y una Closure que define las columnas relacionadas:

$latestPosts = DB::table('posts')
                    ->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
                    ->where('is_published', true)
                    ->groupBy('user_id');

$users = DB::table('users')
        ->joinSub($latestPosts, 'latest_posts', function ($join) {
            $join->on('users.id', '=', 'latest_posts.user_id');
        })->get();

# Uniones

El constructor de consultas también proporciona una forma rápida para "unir" dos consultas. Por ejemplo, puedes crear una consulta inicial y usar el método union para unirlo con una segunda consulta:

$first = DB::table('users')
            ->whereNull('first_name');

$users = DB::table('users')
            ->whereNull('last_name')
            ->union($first)
            ->get();

TIP

El método unionAll también está disponible y tiene la misma forma de uso que union.

# Cláusulas where

# Cláusula where simple

Puedes usar el método where en una instancia del constructor de consultas para añadir cláusulas where a la consulta. La ejecución más básica de where requiere tres argumentos. El primer argumento es el nombre de la columna. El segundo argumento es un operador, el cual puede ser cualquiera de los operadores soportados por la base de datos. Finalmente, el tercer argumento es el valor a evaluar contra la columna.

Por ejemplo, aquí está una consulta que verifica que el valor de la columna "votes" sea igual a 100:

$users = DB::table('users')->where('votes', '=', 100)->get();

Por conveniencia, si quieres verificar que una columna sea igual a un valor dado, puedes pasar directamente el valor como el segundo argumento del método where.

$users = DB::table('users')->where('votes', 100)->get();

Puedes usar otros operadores cuando estés escribiendo una cláusula where:

$users = DB::table('users')
                ->where('votes', '>=', 100)
                ->get();

$users = DB::table('users')
                ->where('votes', '<>', 100)
                ->get();

$users = DB::table('users')
                ->where('name', 'like', 'T%')
                ->get();

También puedes pasar un arreglo de condiciones a la función where:

$users = DB::table('users')->where([
    ['status', '=', '1'],
    ['subscribed', '<>', '1'],
])->get();

# Instrucciones or

Puedes encadenar en conjunto las restricciones where así como añadir cláusulas or a la consulta. El método orWhere acepta los mismos argumentos que el método where:

$users = DB::table('users')
                    ->where('votes', '>', 100)
                    ->orWhere('name', 'John')
                    ->get();

# Cláusulas where adicionales

whereBetween / orWhereBetween

El método whereBetween verifica que un valor de columna esté en un intervalo de valores:

$users = DB::table('users')
                    ->whereBetween('votes', [1, 100])->get();

whereNotBetween / orWhereNotBetween

El método whereNotBetween verifica que un valor de columna no esté en un intervalo de valores:

$users = DB::table('users')
                    ->whereNotBetween('votes', [1, 100])
                    ->get();

whereIn / whereNotIn / orWhereIn / orWhereNotIn

El método whereIn verifica que un valor de una columna dada esté contenido dentro del arreglo dado:

$users = DB::table('users')
                    ->whereIn('id', [1, 2, 3])
                    ->get();

El método whereNotIn verifica que el valor de una columna dada no esté contenido en el arreglo dado:

$users = DB::table('users')
                    ->whereNotIn('id', [1, 2, 3])
                    ->get();

whereNull / whereNotNull / orWhereNull / orWhereNotNull

El método whereNull verifica que el valor de una columna dada sea NULL:

$users = DB::table('users')
                    ->whereNull('updated_at')
                    ->get();

El método whereNotNull verifica que el valor dado de una columna no sea NULL:

$users = DB::table('users')
                    ->whereNotNull('updated_at')
                    ->get();

whereDate / whereMonth / whereDay / whereYear / whereTime

El método whereDate puede ser usado para comparar el valor de una columna contra una fecha:

$users = DB::table('users')
                ->whereDate('created_at', '2016-12-31')
                ->get();

El método whereMonth puede ser usado para comparar el valor de una columna contra un mes específico de un año:

$users = DB::table('users')
                ->whereMonth('created_at', '12')
                ->get();

El método whereDay puede ser usado para comparar el valor de una columna contra un día especíco de un mes:

$users = DB::table('users')
                ->whereDay('created_at', '31')
                ->get();

El método whereYear puede ser usado para comparar el valor de una columna contra un año específico:

$users = DB::table('users')
                ->whereYear('created_at', '2016')
                ->get();

El método whereTime puede ser usado para comparar el valor de una columna contra una hora específica:

$users = DB::table('users')
                ->whereTime('created_at', '=', '11:20')
                ->get();

whereColumn / orWhereColumn

El método whereColumn puede ser usado para verificar que dos columnas son iguales:

$users = DB::table('users')
                ->whereColumn('first_name', 'last_name')
                ->get();

También puedes pasar un operador de comparación al método:

$users = DB::table('users')
                ->whereColumn('updated_at', '>', 'created_at')
                ->get();

Al método whereColumn también le puede ser pasado un arreglo de condiciones múltiples. Estas condiciones serán juntadas usando el operador and:

$users = DB::table('users')
                ->whereColumn([
                    ['first_name', '=', 'last_name'],
                    ['updated_at', '>', 'created_at']
                ])->get();

# Agrupando parámetros

Algunas veces puedes necesitar crear cláusulas where más avanzadas como cláusulas "where exists" o grupos de parámetros anidados. El constructor de consultas de Laravel puede manejar éstos también. Para empezar, vamos a mirar un ejemplo de grupos de restricciones encerrado por llaves:

DB::table('users')
            ->where('name', '=', 'John')
            ->where(function ($query) {
                $query->where('votes', '>', 100)
                        ->orWhere('title', '=', 'Admin');
            })
            ->get();

Como puedes ver, al pasar una Closure dentro del método orWhere, instruyes al constructor de consultas para empezar un grupo de restricción. La Closure recibirá una instancia del constructor de consultas la cual puedes usar para establecer las restricciones que deberían estar contenidas dentro del grupo encerrado por llaves. El ejemplo de arriba producirá la siguiente instrucción SQL:

select * from users where name = 'John' and (votes > 100 or title = 'Admin')

TIP

Siempre debes agrupar llamadas orWhere para evitar comportamiento inesperado cuando se apliquen alcances globales.

# Cláusulas where exists

El método whereExists permite que escribas cláusulas de SQL whereExists. El método whereExists acepta un argumento de tipo Closure, el cual recibirá una instancia del constructor de consultas permitiendo que definas la consulta que debería ser puesta dentro de la cláusula "exists":

DB::table('users')
            ->whereExists(function ($query) {
                $query->select(DB::raw(1))
                        ->from('orders')
                        ->whereRaw('orders.user_id = users.id');
            })
            ->get();

La consulta anterior producirá el siguiente SQL:

select * from users
where exists (
    select 1 from orders where orders.user_id = users.id
)

# Cláusulas where JSON

Laravel también soporta consultar tipos de columna JSON en bases de datos que proporcionan soporte para tipos de columna JSON. Actualmente, esto incluye MySQL 5.7, PostgresSQL, SQL Server 2016, y SQLite 3.9.0 (con la extensión JSON1). Para consultar una columna JSON, usa el operador ->:

$users = DB::table('users')
                ->where('options->language', 'en')
                ->get();

$users = DB::table('users')
                ->where('preferences->dining->meal', 'salad')
                ->get();

Puedes usar whereJsonContains para consultar arreglos JSON (sin soporte en SQLite):

$users = DB::table('users')
                ->whereJsonContains('options->languages', 'en')
                ->get();

MySQL and PostgreSQL proveen soporte para whereJsonContains con múltiples valores:

$users = DB::table('users')
                ->whereJsonContains('options->languages', ['en', 'de'])
                ->get();

Puedes usar whereJsonLength para consultar arreglos JSON por su longitud:

$users = DB::table('users')
                ->whereJsonLength('options->languages', 0)
                ->get();

$users = DB::table('users')
                ->whereJsonLength('options->languages', '>', 1)
                ->get();

# Ordenamiento, agrupamiento, límite y desplazamiento

# orderBy

El método orderBy permite que ordenes los resultados de la consulta por una columna dada. El primer argumento para el método orderBy debería ser la columna por la cual deseas ordenar, mientra que el segundo argumento controla la dirección del ordenamiento y puede ser asc o desc:

$users = DB::table('users')
                ->orderBy('name', 'desc')
                ->get();

# latest / oldest

Los métodos latest y oldest te permiten ordenar fácilmente los resultados por fecha. Por defecto, el resultado será ordenado por la columna created_at. También, puedes pasar el nombre de la columna por la cual deseas ordenar:

$user = DB::table('users')
                ->latest()
                ->first();

# inRandomOrder

El método inRandomOrder puede ser usado para ordenar los resultados de la consulta aletoriamente. Por ejemplo, puedes usar este método para obtener un usuario aleatorio:

$randomUser = DB::table('users')
                ->inRandomOrder()
                ->first();

# groupBy / having

Los métodos groupBy y having pueden ser usados para agrupar los resultados de la consulta. La forma que distingue el uso del método having es similar a la que tiene el método where:

$users = DB::table('users')
                ->groupBy('account_id')
                ->having('account_id', '>', 100)
                ->get();

Puedes pasar argumentos múltiples al método groupBy para agrupar por múltiples columnas:

$users = DB::table('users')
                ->groupBy('first_name', 'status')
                ->having('account_id', '>', 100)
                ->get();

Para instrucciones having más avanzadas, echa un vistazo al método havingRaw.

# skip / take

Para limitar el número de resultados devueltos desde la consulta, o para avanzar un número dado de resultados en la consulta, puedes usar los métodos skip y take:

$users = DB::table('users')->skip(10)->take(5)->get();

Alternativamente, puedes usar los métodos limit y offset:

$users = DB::table('users')
                ->offset(10)
                ->limit(5)
                ->get();

# Cláusulas condicionales

Algunas podrías querer que las cláusulas apliquen solamente a una consulta cuando alguna cosa más se cumple. Por ejemplo, puedes querer que solamente se aplique una instrucción where si un valor de entrada dado está presente en la solicitud entrante. Puedes acompañar esto usando el método when:

$role = $request->input('role');

$users = DB::table('users')
                ->when($role, function ($query) use ($role) {
                    return $query->where('role_id', $role);
                })
                ->get();

El método when ejecuta solamente la Closure dada cuando el primer parámetro es true. Si el primer parámetro es false, la Closure no será ejecutada.

Puedes pasar otra Closure como tercer parámetro del método when. Esta Closure se ejecutará si el primer parámetro se evalúa como false. Para ilustrar cómo esta característica puede ser usada, la usaremos para configurar el ordenamiento predeterminado de una consulta:

$sortBy = null;

$users = DB::table('users')
                ->when($sortBy, function ($query) use ($sortBy) {
                    return $query->orderBy($sortBy);
                }, function ($query) {
                    return $query->orderBy('name');
                })
                ->get();

# Inserciones

El constructor de consultas también proporciona un método insert para insertar registros dentro de la base de datos. El método insert acepta un arreglo de nombres de columna y valores:

DB::table('users')->insert(
    ['email' => 'john@example.com', 'votes' => 0]
);

Incluso puedes insertar varios registros dentro de la tabla con una sola llamada a insert pasando un arreglo de arreglos. Cada arreglo representa una fila a ser insertada dentro de la tabla:

DB::table('users')->insert([
    ['email' => 'taylor@example.com', 'votes' => 0],
    ['email' => 'dayle@example.com', 'votes' => 0]
]);

# IDs de auto-incremento

Si la tabla tiene un id de auto-incremento, usa el método insertGetId para insertar un registro y recibir el ID:

$id = DB::table('users')->insertGetId(
    ['email' => 'john@example.com', 'votes' => 0]
);

Nota

Cuando estás usando PostgreSQL el método insertGetId espera que la columna de auto-incremento sea llamada id. Si prefieres obtener el ID con una "secuencia" distinta, puedes pasar el nombre de la columna como segundo parámetro del método insertGetId.

# Actualizaciones

Además de insertar registros dentro de la base de datos, el constructor de consultas también puede actualizar registros existentes usando el método update. El método update, como el método insert, acepta un arreglo de pares de columna y valor que contienen las columnas a ser actualizadas. Puedes restringir la consulta update usando cláusulas where:

DB::table('users')
            ->where('id', 1)
            ->update(['votes' => 1]);

# Actualizar o insertar

A veces es posible que desees actualizar un registro existente en la base de datos o crearlo si no existe un registro coincidente. En este escenario, se puede usar el método updateOrInsert. El método updateOrInsert acepta dos argumentos: un arreglo de condiciones para encontrar el registro y un arreglo de columnas y pares de valores que contienen las columnas que se actualizarán.

El método updateOrInsert intentará primero buscar un registro de base de datos que coincida con los pares de columna y valor del primer argumento. Si el registro existe, se actualizará con los valores del segundo argumento. Si no se encuentra el registro, se insertará un nuevo registro con los atributos combinados de ambos argumentos:

DB::table('users')
    ->updateOrInsert(
        ['email' => 'john@example.com', 'name' => 'John'],
        ['votes' => '2']
    );

# Actualizando columnas JSON

Cuando estamos actualizando una columna JSON, deberías usar la sintaxis -> para acceder a la clave apropiada en el objeto JSON. Esta operación es soportada solamente en MySQL 5.7+ y PostgreSQL 9.5+:

DB::table('users')
            ->where('id', 1)
            ->update(['options->enabled' => true]);

# Incremento y decremento

El constructor de consultas también proporciona métodos convenientes para incrementar o decrementar el valor de una columna dada. Esto es un atajo, que proporciona una interfaz más expresiva y concisa en comparación con la escritura manual de la declaración update.

Ambos métodos aceptan al menos un argumento: la columna a modificar. Un segundo argumento puede ser pasado opcionalmente para controlar la cantidad con la cual la columna debería ser incrementada o decrementada:

DB::table('users')->increment('votes');

DB::table('users')->increment('votes', 5);

DB::table('users')->decrement('votes');

DB::table('users')->decrement('votes', 5);

También puedes especificar columnas adicionales para actualizar durante la operación:

DB::table('users')->increment('votes', 1, ['name' => 'John']);

# Eliminaciones

El constructor de consultas también puede ser usado para eliminar registros de la tabla por medio del método delete. Puedes restringir instrucciones delete al agregar cláusulas where antes de ejecutar el método delete:

DB::table('users')->delete();

DB::table('users')->where('votes', '>', 100)->delete();

Si deseas truncar la tabla completa, lo cual remueve todas las filas y reinicia el ID de auto-incremento a cero, puedes usar el método truncate:

DB::table('users')->truncate();

# Bloqueo pesimista

El constructor de consultas también incluye algunas funciones que ayudan a que hagas el "bloqueo pesimista" en tus instrucciones select. Para ejecutar la instrucción con un "bloqueo compartido", puedes usar el método sharedLock en una consulta. Un bloqueo compartido previene las filas seleccionadas para que no sean modificadas hasta que tu transacción se confirme:

DB::table('users')->where('votes', '>', 100)->sharedLock()->get();

Alternativamente, puedes usar el método lockForUpdate. Un bloqueo "para actualización" evita que las filas se modifiquen o que se seleccionen con otro bloqueo compartido:

DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();

Puedes usar los métodos dd o dump al construir una consulta para vaciar los enlaces de consulta y SQL. El método dd mostrará la información de depuración y luego dejará de ejecutar la solicitud. El método dump mostrará la información de depuración pero permitirá que la solicitud se siga ejecutando:

DB::table('users')->where('votes', '>', 100)->dd();

DB::table('users')->where('votes', '>', 100)->dump();