laravellaravel-5.7nvarcharlaravel-migrationslaravel-schema-builder

Add varchar column type with SQL Server using Laravel


I'm using Laravel 5.7 along with SQL Server 2017 and I want to generate a varchar(50) column called name.

Executing this code gives me a nvarchar(50) instead:

Schema::create('test', function(Blueprint $table) {
    $table->string('name', 50);
});

How can I differentiate between creating a varchar or nvarchar field?


Solution

  • This is a shot in the dark as I don't have SQL Server to test. But basically you can just extend the Blueprint and SqlServerGrammar classes and add your own column types. Please test and let me know. :)

    Create a folder called Schemas under the app folder, then create folders Blueprints and Grammars under the Schemas folder. Inside them, create your PHP classes:

    Schemas file structure

    CustomBlueprint.php

    <?php
    
    namespace App\Schemas\Blueprints;
    
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Schema\Builder;
    
    class CustomBlueprint extends Blueprint
    {
        public function varChar($column, $length = null)
        {
            $length = $length ? : Builder::$defaultStringLength;
    
            return $this->addColumn('varChar', $column, compact('length'));
        }
    }
    

    CustomGrammar.php

    <?php
    
    namespace App\Schemas\Grammars;
    
    use Illuminate\Database\Schema\Grammars\SqlServerGrammar;
    use Illuminate\Support\Fluent;
    
    class CustomGrammar extends SqlServerGrammar
    {
        protected function typeVarChar(Fluent $column)
        {
            return "varchar({$column->length})";
        }
    }
    

    Your migration file:

    public function up()
    {
        DB::connection()->setSchemaGrammar(new CustomGrammar());
    
        $schema = DB::connection()->getSchemaBuilder();
    
        $schema->blueprintResolver(function($table, $callback) {
            return new CustomBlueprint($table, $callback);
        });
    
        $schema->create('test', function (CustomBlueprint $table) {
            $table->string('name', 50);  // <-- nvarchar(50)
            // or
            $table->varChar('name', 50); // <-- varchar(50)
        });
    }