如何使用Eloquent删除表中的所有行?


135

我的猜测是使用以下语法:

MyModel::all()->delete();

但这没有用。我敢肯定它非常简单,但是我已经搜索了有关该主题的文档,但找不到它!

Answers:


279

原因MyModel::all()->delete()不起作用是因为all()实际上触发了查询并返回了Eloquent对象的集合。

您可以使用truncate方法,这适用于Laravel 4和5:

MyModel::truncate();

这将删除表中的所有行,而无需记录单个行的删除。


1
我为我的问题添加了Laravel 3解决方案,以供将来的读者使用。
皮特

39
真好 在Laravel 5本作品太多,如果这里还有其他谷歌自己在2016年
samiles

14
注意:truncate()还会重置任何AUTO_INCREMENT计数器(还请注意,您不能截断具有外键约束的表。)
William Turrell

10
仅供参考:Turncate不会触发删除事件。
Fusion

1
如果您真的要使用MyModel::all()->delete(),请使用foreach (MyModel::all() as $e) { $e->delete() }
Ema4rl'1

70

Laravel 5.2+解决方案。

Model::getQuery()->delete();

只需获取具有表名的基础构建器,然后执行任何操作即可。没有比这更整齐的了。

Laravel 5.6解决方案

\App\Model::query()->delete();

9
如果任何人感到困惑,为什么这个作品,通过__call魔术方法Model类方法转发到Builder 这里。因为模型类本身具有删除方法,所以当您确实需要Builder方法时,调用Model :: delete()会调用Model方法。因此,要明确获取构建器,可以使用getQuery()。
kevinAlbs

如果需要,这也不会删除相关表。
Terje Nesthus

它将强制删除所有记录,而不管软删除是打开还是关闭
shalini

型号:: whereNotNull('id')-> delete(); -启用软删除功能时,将进行软删除
shalini

61

您可以使用Model::truncate()是否禁用foreign_key_checks(我假设您使用MySQL)。

DB::statement("SET foreign_key_checks=0");
Model::truncate();
DB::statement("SET foreign_key_checks=1");

2
在Laravel 4中,您使用DB ::
unprepared

您也可以使用Schema :: disableForeignKeyConstraints(); &Schema :: enableForeignKeyConstraints();
Eleazar Resendez,

33

我已经看到在种子文件中使用了这两种方法。

// Uncomment the below to wipe the table clean before populating

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

//or

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

即使要设置外键也不能使用第一个。

无法截断外键约束中引用的表

因此,使用第二个可能是一个好主意。


2
delete显然是不一样的truncate
乔尔·梅隆

2
@sudopeople指出区别确实很有帮助。我也可以将其添加到我的答案中
giannis christofakis 2014年

4
TRUNCATE不能在事务中使用,因为它不受ROLLBACK的影响。在这种情况下,可以通过(new MyModel)-> newQuery()-> delete()来实现。
hammurabi 2014年

12

有一种间接方式:

myModel:where('anyColumnName', 'like', '%%')->delete();

例:

User:where('id', 'like' '%%')->delete();

Laravel查询构建器信息:https ://laravel.com/docs/5.4/queries


1
@aschipfl实际上没有太多解释。该代码运行DELETE FROM users WHERE id LIKE '%%'与表中所有行匹配的SQL ,从而删除所有内容。
Hkan 2015年

这让我迷路了。我最后在另一个模型上执行pluck()以获得所需的ID数组,然后使用该数组使用以下whereIn方法从我的模型中删除所有记录: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC

9

我想为那些通过Google进入该话题的人添加另一个选择。我需要完成此操作,但想保留自动truncate()重置的值。我也不想使用DB::任何东西,因为我想直接在模型对象之外进行操作。所以,我这样做了:

Model::whereNotNull('id')->delete();

显然,该列实际上必须存在,但是在标准的即开即用的Eloquent模型中,该id列存在并且永远不会为空。我不知道这是否是最佳选择,但它可以满足我的目的。


Model::delete();将完成同样的事情。
Leng

5
不幸的是,至少在Laravel 5.0中Model::delete()引发了异常Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically
戴夫·詹姆斯·米勒

6

我无法使用,Model::truncate()因为它会出错:

SQLSTATE [42000]:语法错误或访问冲突:1701无法截断外键约束中引用的表

不幸的Model::delete()是,它不起作用(至少在Laravel 5.0中):

非静态方法Illuminate \ Database \ Eloquent \ Model :: delete()不应以静态方式调用,假设$ this来自不兼容的上下文

但这确实有效:

(new Model)->newQuery()->delete()

如果您设置了软删除,则将软删除所有行。要完全删除所有行,包括软删除的行,可以更改为:

(new Model)->newQueryWithoutScopes()->forceDelete()

4

完成此操作的最好方法Laravel 3似乎是使用Fluent接口截断表,如下所示

DB::query("TRUNCATE TABLE mytable");

2

您也可以尝试使用这种保留软删除功能的单线:

Model::whereRaw('1=1')->delete();


0

与Travis vignon的回答类似,我需要雄辩的模型中的数据,如果条件正确,则需要删除或更新模型。我最终获得了查询返回的最小值和最大值(如果向表中添加了满足我的选择条件的其他字段)以及原始选择条件,以通过一个原始SQL查询(如而不是对集合中的每个对象进行一次雄辩的查询)。

我知道原始SQL的使用违反了laravels漂亮的代码哲学,但是很难忍受数百个查询来代替一个查询。


0

可以做一个 循环也..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

从技术上讲是...但是IMO似乎没有必要,因为有更好的单个查询选项。
皮特

@Pete我知道..别人已经给他们的答案......我试图回答其他可能的方法来做..
萨姆·所罗门

1
这实际上对我有用,因为我计划根据特定规则将集合中的模型存档,而且还要从该日常活动表中清除它们。
James Perih '16

-1

在外键约束下使用Lumen 5.5的解决方案:

$categories = MusicCategory::all();
foreach($categories as $category)
{
$category->delete();

}
return response()->json(['error' => false]);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.