Итак, у меня возникла проблема, когда я вставляю данные в базу данных 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.






Вы можете использовать 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');
Работает 100%. Спасибо
Для справки см. Laravel issue это.
Если вы получаете сообщение об ошибке утверждения, попробуйте этот обходной путь:
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, что и в других средах, в которых этой проблемы не было.
@ Брайан, дай мне знать, если это поможет.