Вставка данных в laravel IDENTITY_INSERT отключена

Итак, у меня возникла проблема, когда я вставляю данные в базу данных sqlserver. id sqlserver отказывается вставлять, потому что база данных хочет вставить id сама.

я должен попытаться установить IDENTITY_INSERT ON следующим образом:

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]Cannot insert explicit value for identity column in table 'articles' when IDENTITY_INSERT is set to OFF.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
0
2 755
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать 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');

@ Брайан, дай мне знать, если это поможет.

Vikash Pathak 18.06.2019 03:08

Работает 100%. Спасибо

rogervila 21.02.2020 12:04

Для справки см. Laravel issue это.

shmuels 02.09.2020 22:18

Если вы получаете сообщение об ошибке утверждения, попробуйте этот обходной путь:

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');

Как упомянул Викаш Патхак, DB::unprepared будет работать, хотя в моем случае я столкнулся с проблемой запуска этого на macOS, когда у меня был установлен Doctrine DBAL (уровень абстракции базы данных), который является зависимостью от Laravel Nova. Оказывается, DB::unprepared вернет false для этого оператора, который работает нормально, за исключением того, что DBAL вызовет ошибку утверждения.

 AssertionError 

  assert($result !== false)

  at vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:54

Я боролся с рядом подходов, чтобы обойти это, но в конечном итоге я обнаружил, что, добавив тривиальный SELECT перед SET IDENTITY_INSERT table_name ON, он вернет true, и AssertionError больше не будет проблемой.

Пожалуйста, дайте мне знать, если есть более элегантное решение. Возможно, моей конкретной проблемой была особенность драйвера или настройка БД, но я использую ту же конфигурацию Docker SQL Server 2019, что и в других средах, в которых этой проблемы не было.

Другие вопросы по теме