【问题标题】:Insert data in laravel IDENTITY_INSERT is set to OFF在 laravel 中插入数据 IDENTITY_INSERT 设置为 OFF
【发布时间】:2021-08-29 02:02:28
【问题描述】:

所以我在数据库 sqlserver 上插入数据时遇到了问题。 id sqlserver 拒绝插入,因为数据库要自己插入 id。

我必须尝试像这样设置 IDENTITY_INSERT :

DB::statement('SET IDENTITY_INSERT articles ON;');

并将 IDENTITY_INSERT 设置为 OFF,如下所示:

DB::statement('SET IDENTITY_INSERT articles OFF;');

但这不适用于我的代码。

   public function store(Request $request){
        //to sparate to methode
        $article = $request->isMethod('put') ? Article::findOrFail($request->article_id) : new Article;

        $article->id = $request->input('article_id');
        $article->title = $request->input('title');
        $article->body = $request->input('body');

        DB::statement('SET IDENTITY_INSERT articles ON;');
        if($article->save()){
            return new ArticleResources($article);
        }
        DB::statement('SET IDENTITY_INSERT articles OFF;');

    }

这个错误看起来像这样:

SQLSTATE[23000]:[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]当 IDENTITY_INSERT 设置为 OFF 时,无法为表“articles”中的标识列插入显式值。

【问题讨论】:

    标签: laravel sqlsrv


    【解决方案1】:

    您可以使用DB::unprepared() 代替DB::statement()

    不同之处在于statement() 执行准备好的语句,而unprepared() 使用PDO::exec() 代替。

    每个准备好的语句都会启动一个新会话(在同一个数据库连接内),并且因为 SET IDENTITY_INSERT 查询是特定于会话的,它不会影响其他准备好的语句,例如 INSERT 查询。

    PDO::exec() 影响整个数据库连接。

    喜欢:

    DB::unprepared('SET IDENTITY_INSERT test_table ON');
    DB::table('articles')->insert(['id' => $request->input('article_id'), 'title' => $request->input('title'), 'body'=> $request->input('body')]);
    DB::unprepared('SET IDENTITY_INSERT test_table OFF');
    
    

    【讨论】:

    • @Brian 让我知道是否有帮助。
    • 工作 100%。谢谢
    • 参见this laravel issue 以供参考。
    【解决方案2】:

    如果您遇到断言错误,请尝试以下解决方法:

    DB::unprepared('SELECT 1; SET IDENTITY_INSERT test_table ON');
    DB::table('articles')->insert(['id' => $request->input('article_id'), 'title' => $request->input('title'), 'body'=> $request->input('body')]);
    DB::unprepared('SELECT 1; SET IDENTITY_INSERT test_table OFF');
    

    正如 Vikash Pathak 所提到的,DB::unprepared 可以工作,尽管在我的情况下,当我安装 Doctrine DBAL(数据库抽象层)时,我在 macOS 上运行它时遇到了问题,这是 Laravel Nova 的一个依赖项。事实证明,DB::unprepared 将为此语句返回 false,除了 DBAL 会导致断言错误之外,它运行良好。

     AssertionError 
    
      assert($result !== false)
    
      at vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:54
    

    我尝试了多种方法来解决这个问题,但最终我发现,通过在 SET IDENTITY_INSERT table_name ON 之前添加一个简单的 SELECT,它会返回 true 并且 AssertionError 将不再是问题。

    如果有更优雅的解决方案,请告诉我。我的特定问题可能是驱动程序怪癖或 DB 设置,但我使用的 Docker SQL Server 2019 配置与其他没有此问题的环境相同。

    【讨论】:

      猜你喜欢
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多