如何使用Laravel 5.1执行原始查询?

114

我需要在我的数据库上运行一个小查询,在MySQL Workbench中它能够正常工作。基本上,这是一个带有LEFT JOIN的SELECT语句和一个带有LEFT JOIN的UNION语句。

SELECT
    cards.id_card,
    cards.hash_card,
    cards.`table`,
    users.name,
    0 as total,
    cards.card_status,
    cards.created_at
FROM cards
LEFT JOIN users
ON users.id_user = cards.id_user
WHERE hash_card NOT IN ( SELECT orders.hash_card FROM orders )
UNION
SELECT
    cards.id_card,
    orders.hash_card,
    cards.`table`,
    users.name,
    sum(orders.quantity*orders.product_price) as total, 
    cards.card_status, 
    max(orders.created_at) 
FROM menu.orders
LEFT JOIN cards
ON cards.hash_card = orders.hash_card
LEFT JOIN users
ON users.id_user = cards.id_user
GROUP BY hash_card
ORDER BY id_card ASC

我试图将它翻译成Laravel,但没有成功。

$cards = Card::selectRaw('cards.id_card, cards.hash_card ,cards.table, users.name, 0 as total, cards.card_status, cards.created_at as last_update')
                ->leftJoin('users','users.id_user','=','cards.id_user')
                ->whereNotIn( 'hash_card', Order::select('orders.hash_card')->get() )
                ->union(
                        Order::selectRaw('cards.id_card, orders.hash_card, cards.table, users.name, sum(orders.quantity*orders.product_price) as total, cards.card_status, max(orders.created_at) as last_update')
                        ->leftJoin('cards','cards.hash_card','=','orders.hash_card')
                        ->leftJoin('users','users.id_user','=','cards.id_user')
                )
                ->groupBy('hash_card')
                ->orderBy('cards.id_card','asc')
                ->get();

我遇到了以下错误信息:

ErrorException in Builder.php line 1249: Undefined property: Illuminate\Database\Eloquent\Builder::$bindings

在Laravel中,我应该如何执行完全原始的查询或以正确的方式编写查询语句?

5个回答

227

我在这个主题中找到了解决方案,然后我写下了以下代码:

$cards = DB::select("SELECT
        cards.id_card,
        cards.hash_card,
        cards.`table`,
        users.name,
        0 as total,
        cards.card_status,
        cards.created_at as last_update
    FROM cards
    LEFT JOIN users
    ON users.id_user = cards.id_user
    WHERE hash_card NOT IN ( SELECT orders.hash_card FROM orders )
    UNION
    SELECT
        cards.id_card,
        orders.hash_card,
        cards.`table`,
        users.name,
        sum(orders.quantity*orders.product_price) as total, 
        cards.card_status, 
        max(orders.created_at) last_update 
    FROM menu.orders
    LEFT JOIN cards
    ON cards.hash_card = orders.hash_card
    LEFT JOIN users
    ON users.id_user = cards.id_user
    GROUP BY hash_card
    ORDER BY id_card ASC");

6
实际上,你甚至不需要嵌套使用DB::Raw函数。你只需调用DB::select("...你的查询语句...")即可。 - Jimmy Zoto
4
我可以帮忙翻译。以下是翻译的内容:我有一个问题,请问一下。在 Laravel 5(确切地说是5.3)中,使用查询构建器通过原始 SQL 查询(带或不带 DB::raw)足以防止 SQL 注入吗?我找到了一些相关文章,但它们都是针对 Laravel 4 的。我找不到令人信服的确认信息。 - Robert
2
仅使用DB :: select无法防止SQL注入攻击。但是,通过确保所有用户提供的输入都经过$ safe_string = DB :: connection() - > getPdo() - > quote($ string)处理,您可以保护您的代码。 - ftrotter
6
为了防止 SQL 注入攻击,您可以将参数绑定到原始查询中。请参考文档 https://laravel.com/docs/5.5/database#running-queries。 - Jabari
我相信你可以通过在原始查询中添加“LIMIT”和“OFFSET”来实现 -> https://www.bitdegree.org/learn/mysql-limit-offset - Sandro Wiggers
显示剩余3条评论

54
    DB::statement("your query")

我在迁移中使用它为列添加索引


3

Laravel文档中的示例:

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

另一个例子:
$products = DB::table('products')
    ->leftjoin('category','category.product_id','=','products.id')
    ->selectRaw('COUNT(*) as nbr', 'products.*')
    ->groupBy('products.id')
    ->get();

另一个例子 - 我们甚至可以在同一条语句中执行avg()和count()。

$salaries = DB::table('salaries')
    ->selectRaw('companies.name as company_name, avg(salary) as avg_salary, count(*) as people_count')
    ->join('companies', 'salaries.company_id', '=', 'companies.id')
    ->groupBy('companies.id')
    ->orderByDesc('avg_salary')
    ->get();

Credits: https://blog.quickadminpanel.com/5-ways-to-use-raw-database-queries-in-laravel/


0

另外,你可以使用

DB::unprepared()

-30

你也可以像这样运行原始查询。

DB::table('setting_colleges')->first();

5
这不是 Laravel 中的原始查询方法,它只是获取该表的第一行。 - Root
这是错误的查询。:( - Nilesh Bavliya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接