Last active
December 23, 2017 02:16
-
-
Save spacemudd/abfa7ef66d096f3f20796bf373df365b to your computer and use it in GitHub Desktop.
Laravel and SQL Server 2012 DATETIME issue: PDOException: SQLSTATE[22007]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Support\Facades\Schema; | |
use Illuminate\Database\Schema\Blueprint; | |
use Illuminate\Database\Migrations\Migration; | |
class CreateManufacturersTable extends Migration | |
{ | |
/** | |
* Run the migrations. | |
* | |
* @return void | |
*/ | |
public function up() | |
{ | |
Schema::create('manufacturers', function (Blueprint $table) { | |
$table->increments('id'); | |
// Here, we specify the microseconds' precision digits to be 4 to make a DATETIME2. | |
// If we don't, Laravel will create a DATETIME column type. | |
// And our unit test will fail. | |
$table->datetime('created_at', 4); | |
$table->datetime('updated_at', 4); | |
// We can also use the precision param on timestamps() and timestmap(). | |
// $table->timestamps(4); | |
}); | |
} | |
/** | |
* Reverse the migrations. | |
* | |
* @return void | |
*/ | |
public function down() | |
{ | |
Schema::dropIfExists('manufacturers'); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Tests\Unit; | |
use App\Models\Manufacturer; | |
use Carbon\Carbon; | |
use Tests\TestCase; | |
use Illuminate\Foundation\Testing\WithFaker; | |
use Illuminate\Foundation\Testing\RefreshDatabase; | |
class DateTimeMicrosecondsTest extends TestCase | |
{ | |
public function testDateTimeMicrosecondsTest() | |
{ | |
/** | |
* Saving this record in SQL Server 2012 will result in the following error. | |
* | |
* PDOException: SQLSTATE[22007]: [Microsoft][ODBC Driver 13 for SQL Server] | |
* [SQL Server]Conversion failed when converting date and/or time from | |
* character string. | |
* | |
* Because Laravel defaults to creating a DATETIME column when using migration | |
* method datetime(); on SQL Servers. SQL Servers limits to the nanoseconds | |
* parts to 3 DIGITS ONLY. | |
* | |
* In order to save and retrieve DATETIME values with 4+ digits on the | |
* microseconds part, specify the precision on the migration method | |
* $table->datetime(4); and this precision works too for: | |
* | |
* $table->timestamp(4), $table->timestamps(4) and $table->datetimeTz(4) | |
* | |
*/ | |
$newManufacturer = new Manufacturer(); | |
$newManufacturer->code = '123'; | |
// This test also fails (using DATETIME columns) if you comment | |
// these two lines out and allow Eloquent to set | |
// created_at and updated_at datetimes. | |
$newManufacturer->created_at = '2017-12-22 13:46:36.1335'; | |
$newManufacturer->updated_at = '2017-12-22 13:46:36.1335'; | |
$newManufacturer->save(); | |
// SQL Server's engine rounds the microseconds up. | |
$this->assertDatabaseHas('manufacturers', ['created_at' => '2017-12-22 13:46:36.1340']); | |
} | |
public function tearDown() | |
{ | |
Manufacturer::where('code', '123')->delete(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment