Laravel 4:如何运行原始SQL?

90

我想在Laravel 4中重命名一张表,但不知道如何操作。

SQL语句是alter table photos rename to images。如果有Eloquent解决方案,我也想知道如何运行原始的SQL,因为有时没有其他选择。

7个回答

163

Laravel 4手册中,它谈论了如何执行原始命令,就像这样:

DB::select(DB::raw('RENAME TABLE photos TO images'));

编辑:我刚在Laravel 4文档中找到了这个内容,可能更好一些:

DB::statement('drop table users');

更新: 在 Laravel 4.1 (也许是4.0 - 我不确定)中,您也可以对原始的Where查询执行此操作:

$users = User::whereRaw('age > ? and votes = 100', array(25))->get();

进一步更新 如果你想具体重命名表格 - 有一个专门的模式命令可以实现 - 参见下面Mike的答案。


4
有一个实际的Schema::rename($from, $to)函数,Mike Branski在下面提到了。使用它,无论数据库如何,都可以正常工作。 - trm42
为什么这个回答被接受了,而它并没有使用正确的L4方法 Schema::rename($from, $to),正如我、@trm42和@Mike Branski所提到的那样?请考虑更改它,以便为其他观众提供最新的答案。 - Sean the Bean
2
因为标题是“如何运行原始SQL?”,但问题包括重命名表的示例。问题还说“我也想知道如何运行原始SQL” - 所以我的答案是针对这部分的。您是正确的,Schema :: rename()函数对于表重命名的特定情况非常有用。 - Laurence
那倒是真的,但我的问题是针对OP @duality_的。(顺便说一句,我质疑这是否应该成为被接受的答案的原因是因为它没有向观众提供现在标准的运行原始查询的方法,如http://laravel.com/docs/4.2/database#running-queries所记录的。事实上,你的陈述“还有一些命令可以进行模式更改——但重命名表不是其中之一。”自2013年2月以来就不再正确了。如果你想让这个答案保持被接受的状态,我建议你更新它,使其对未来的观众更有用。) - Sean the Bean

17

4
现在这个功能已经在 Laravel 4 和 Laravel 4.1 的文档中被记录下来了。 - trm42

15
你也可以使用DB::unprepared来执行ALTER TABLE查询。 DB::unprepared主要用于执行类似于CREATE TRIGGER的查询。但它本质上直接执行原始的SQL查询。(不使用PDO prepared语句) https://github.com/laravel/framework/pull/54

当我想使用DB :: query(“SET foreign_key_checks = 0”)时,它对我有效。 - swdev
1
@swdev:PDO支持SET queries。但是使用DB::query(PDO::query)将会不必要地创建一个预处理语句,因为上面的查询没有变量。 - smitrp

11

到目前为止,我发现最好的方法是绕过Laravel直接使用Pdo对象执行查询。

示例

DB::connection()->getPdo()->exec( $sql );

对于单次查询,我通常发现打开数据库查询工具,输入完整的查询语句并进行语法检查,然后直接执行会更快、更高效。

如果你需要使用存储过程或数据库函数,则这一点变得至关重要。

例2 将created_at设置为所需的值,并规避任何碳杂质。

$sql = 'UPDATE my_table SET updated_at = FROM_UNIXTIME(nonce) WHERE id = ' . strval($this->id);
DB::statement($sql);

我发现这个方法在控制器中可行,但在迁移中却不行。


太棒了,终于有一个可行的解决方案了。我不得不使用这个方法,因为我正在执行 DB::connection()->getPdo()->exec('USE '.$dbConfig['database']);。我在 Laravel 命令中删除并重新创建数据库,所以需要这样做。 - Aditya M P
1
感谢您的回复。我们发现执行原始创建表查询的最简单方法。 - sujivasagam
1
根据$this-> id的位置,它可能容易受到SQL注入攻击。 - North-Pole
在一个字符串中执行多个SQL命令的能力,如果您将任何类型的用户输入注入到任何查询中,那么这是极其危险的。应该在答案中指出这一点。(请参见http://php.net/manual/en/function.pg-escape-string.php或http://php.net/manual/en/mysqli.real-escape-string.php以了解如何防止此问题。)此外,这只回答了OP问题的一半(如何运行原始SQL查询,而不是如何在Laravel 4中重命名表),或者表明有官方解决方案(请参见http://laravel.com/docs/4.2/schema#creating-and-dropping-tables)。我要投反对票。 - Sean the Bean

9
在Laravel 4中重命名表的正规方法是使用Schema构建器。因此,您需要执行以下操作:
Schema::rename('photos', 'images');

来源:http://laravel.com/docs/4.2/schema#creating-and-dropping-tables

如果你真的想要自己编写原始的SQL查询,你可以这样做:

DB::statement('alter table photos rename to images');

注意:Laravel的DB类也支持运行原始的SQL selectinsertupdatedelete查询,例如:
$users = DB::select('select id, name from users');

更多信息请参见http://laravel.com/docs/4.2/database#running-queries。这里介绍了如何运行查询。

3
这是一个简化的示例,演示如何运行原始查询、获取结果并访问值。
$res = DB::select('
        select count(id) as c
        from prices p 
        where p.type in (2,3)
    ');
    if ($res[0]->c > 10)
    {
        throw new Exception('WOW');
    }

如果你想仅运行SQL脚本而无需返回结果,则可以使用以下方式。
DB::statement('ALTER TABLE products MODIFY COLUMN physical tinyint(1) AFTER points;');

已在 Laravel 5.1 中测试通过。


2

Laravel原生SQL - 插入查询:

让我们创建一个可通过URL访问的插入数据链接。我们将链接命名为“insertintodb”,并在该函数中使用db类。db类帮助我们与数据库交互。我们使用db类静态函数insert。在insert函数内,我们将编写用于将数据插入数据库的PDO查询。在下面的查询中,我们将“my title”和“my content”作为数据插入到posts表中。

请将以下代码放入routes目录中的web.php文件中:

Route::get('/insertintodb',function(){
DB::insert('insert into posts(title,content) values (?,?)',['my title','my content']);
});

现在请从以下浏览器链接中执行上面的插入查询:
localhost/yourprojectname/insertintodb

您可以通过进入数据库表来查看上述插入查询的输出。您将找到一条ID为1的记录。

Laravel原始SQL - 读取查询:

现在,让我们创建一个获取链接以读取数据,可通过URL访问。所以我们的链接名称是“readfromdb”。我们使用db类静态函数read。在read函数内部,我们将编写我们的PDO查询以从数据库中读取数据。在下面的查询中,我们将从posts表中读取id为“1”的数据。

请将以下代码放入routes目录中的web.php文件中:

Route::get('/readfromdb',function() {
    $result =  DB::select('select * from posts where id = ?', [1]);
    var_dump($result);
});

现在从下面的浏览器链接中执行上述读取查询:
localhost/yourprojectname/readfromdb

您好,DB::select(...) 中的第二个参数是什么?我在文档中找不到它。请帮忙。 - Yevgeniy Afanasyev

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