I am trying to use SQL Server for my databases with my Laravel project. I was able to connect SQL Server with Laravel 5.2. However, when I try to seed data into the table I get this error
[Illuminate\Database\QueryException] SQLSTATE[23000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Cann ot insert explicit value for identity column in table 'surveys' when IDENTITY_INSERT is set to OFF. (SQL: insert into [surveys] ([id], [name]) values (10, 'Some Text'))
Note: I am trying to supply the identity value which is probably what is causing the problem.
While researching the SQL error, I learned that I need to execute the following queries.
Before seeding I need to execute
SET IDENTITY_INSERT surveys ON;
After the seeding I need to execute
SET IDENTITY_INSERT surveys OFF;
But I am not sure how can I execute these command using Laravel
How can I seed while supplying the value for the identity column without this issue?
UPDATED Here is my seeder
<?php
use Illuminate\Database\Seeder;
class FinalSurveyTS extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$myTable = 'surveys';
DB::statement('SET IDENTITY_INSERT ' . $myTable . ' ON');
DB::table($myTable)->truncate();
DB::table($myTable)->insert([
'id' => 10,
'name' => 'some name',
]);
DB::statement('SET IDENTITY_INSERT ' . $myTable . ' OFF');
}
}
In order to execute those commands, you can do it as raw
and then
DB::statement is supposed for commands that don't return data
Edit When the seeder is executed like this:
Seems that for some reason the state of IDENTITY_INSERT variable is not kept, so a way to make it work is to wrap that code in a transaction.
Because of this, you should follow the way I did for the connection; Here is the sample code;
Here is what I found.
Laravel does not support raw statement inside of a transaction.
Any raw statement will be executed separately with a separate connection to the database.
The means when executing
..
Laravel will process 3 different database connection. This means that the second statement will never be aware of the first or third transaction. There for the first line will have no affect what so ever in this case.
The work around to this problem "until Laravel adds support to the raw statement to the transaction" is to create insert statement as a raw query like so
I hope this post helps someone else.
For anyone finding this via Google - the new correct answer is to use
unprepared()
like this:As discussed on this issue thread: https://github.com/laravel/framework/issues/27778
I ended up creating the following methods to control the
IDENTITY_INSERT
to ON/OFF for SQL table seeding process:Note: Generally, the table requires to have an auto-increment primary key to set Identity Insert to
ON
, that's why I have the$hasAutoIncrementPrimaryKey
flag. Otherwise, seeding may throw an error as:Hope this helps!