Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel / Eloquent - How Do You Run Multiple Raw SQL Statements At the Same Time?

I have multiple SQL statements I'd like to run through Eloquent. They look something like this:

CREATE TEMPORARY TABLE cars
    AS (SELECT cars.id, cars.ip_address
        FROM cars
            JOIN colors ON colors.ip_address = cars.ip_address);

CREATE TEMPORARY TABLE boats
    AS (SELECT ip_address, MIN(id) AS id
        FROM colors
        GROUP BY ip_address);

CREATE TEMPORARY TABLE rvs
    AS (SELECT rvs.id, rvs.ip_address
        FROM rvs
            LEFT JOIN colors ON colors.id = rvs.id
        WHERE colors.id IS NULL);

/* Do things with temp tables here */

I need all of these statements to run in one connection session since they are using temporary tables. I've tried using DB::statement() which errors out at the start of the second statement operation and also DB::unprepared() which doesn't seem to run any of the operations.

Is there a way to run multiple raw statements using Eloquent?

like image 650
Lloyd Banks Avatar asked Jan 06 '17 17:01

Lloyd Banks


People also ask

Can two statements run in one SQL script?

To run a query with multiple statements, ensure that each statement is separated by a semicolon; then set the DSQEC_RUN_MQ global variable to 1 and run the query. When the variable is set to zero, all statements after the first semicolon are ignored.

Which is better eloquent or query builder in Laravel?

When you are handling more data, it is better to use Laravel's DB facade query builder than Laravel's Eloquent ORM. From performance tests, inserting 1000 rows in a simple table takes Eloquent 1.2 seconds whereas the DB facade takes only 800 milliseconds.

What is DB :: Raw in Laravel?

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.


1 Answers

I think you were on the right track with the unprepared statement, but I feel like it's possible that utilizing a transaction may be advantageous in your scenario. Furthermore, you'll want to use \DB::raw() which will execute your SQL statement as a flat string. Of course, do not put anything in here that could be user provided as you'd open yourself up to SQL injection given that you're bypassing parameterized queries.

try {
    \DB::transaction(function(){
        \DB::unprepared(\DB::raw('CREATE TEMPORARY TABLE cars AS (SELECT cars.id, cars.ip_address FROM cars JOIN colors ON colors.ip_address = cars.ip_address)'));

        \DB::unprepared(\DB::raw('CREATE TEMPORARY TABLE boats AS (SELECT ip_address, MIN(id) AS id FROM colors GROUP BY ip_address)'));

        \DB::unprepared(\DB::raw('CREATE TEMPORARY TABLE rvs AS (SELECT rvs.id, rvs.ip_address FROM rvs LEFT JOIN colors ON colors.id = rvs.id WHERE colors.id IS NULL)'));
    });

    \DB::commit();
} catch (\Exception $e){ 
    \DB::rollback();
    //do something with $e->getMessage();
}

Furthermore, this is actually Laravel's Query Builder and not Eloquent.

like image 168
Ohgodwhy Avatar answered Oct 04 '22 19:10

Ohgodwhy