Laravel Livewire编辑MS SQL Server用户表关联字段时触发General error 20018 SET选项错误的解决求助
解决MS SQL Server + Livewire更新User模型时的SET选项错误
这个错误是MS SQL Server的特定限制——当你的表存在索引视图、计算列上的索引、筛选索引、查询通知、XML数据类型方法或空间索引这类对象时,执行UPDATE/INSERT/DELETE操作必须确保几个关键的SET选项处于正确启用状态,而你的Laravel数据库连接默认没有配置这些选项,这就是问题所在。
对比Area表正常工作的原因很简单:Area表大概率没有上述这些特殊的索引结构,所以MS SQL不会强制检查这些SET选项;但User表有这类结构,因此触发了错误。
下面是几个可行的解决方案,按推荐程度排序:
1. 全局配置SQL Server连接的SET选项(推荐)
修改config/database.php中的sqlsrv连接配置,添加options参数来强制设置所需的SET选项:
'sqlsrv' => [ 'driver' => 'sqlsrv', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', '1433'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', 'prefix_indexes' => true, 'options' => [ PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8, // 强制设置MS SQL要求的SET选项 PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 30, 'SET ANSI_NULLS ON', 'SET CONCAT_NULL_YIELDS_NULL ON', 'SET ANSI_WARNINGS ON', 'SET ANSI_PADDING ON', 'SET QUOTED_IDENTIFIER ON', // 如果你的环境需要,可添加TrustServerCertificate // 'TrustServerCertificate' => true, ], ],
修改完成后,执行php artisan config:clear清除配置缓存,然后重新测试更新操作。这个方案会让所有使用该连接的操作都自动满足MS SQL的要求,一劳永逸。
2. 手动在更新方法中执行SET语句
如果暂时不想修改全局配置,可以在updateArea方法中,执行save()之前手动设置这些选项:
public function updateArea($new_area_id){ $this->new_area_id = $new_area_id; $this->validate(); // 针对外部连接手动设置SET选项 DB::connection('ext')->statement('SET ANSI_NULLS ON'); DB::connection('ext')->statement('SET CONCAT_NULL_YIELDS_NULL ON'); DB::connection('ext')->statement('SET ANSI_WARNINGS ON'); DB::connection('ext')->statement('SET ANSI_PADDING ON'); $user = User::findOrFail($this->record_id); $user->area_id = $new_area_id; $user->save(); $this->emit('areaUpdated'); }
这种方法适合临时测试,或者只有个别操作需要这些选项的场景,但每次执行更新都要重复这些语句,不够优雅。
3. 检查并移除User表的特殊索引
如果User表上的索引视图、计算列索引等不是业务必需的,可以考虑删除这些对象。这样MS SQL就不会强制要求设置这些SET选项,错误也会消失。
不过这个方案需要谨慎操作,确保删除这些索引不会影响系统的查询性能或业务逻辑。
内容的提问来源于stack exchange,提问作者Pathros
相关产品推荐
相关产品推荐

