简体   繁体   中英

How to change constraint FOREIGN KEY in mysql 8 from `ON DELETE CASCADE` to `ON DELETE SET NULL` in laravel migration or raw sql

Firstly, my English very bad. Sorry about that.

I have a foreign key in cards table like:

$table->foreignId('wallet_id')->constrained('wallets', 'id')->onDelete('cascade');

Since some reasons I need change cascade to set null on that column

I have try (in a new migration):

$table->dropForeign('cards_wallet_id_foreign');
$table->foreignId('wallet_id')
    ->nullable()
    ->onDelete('set null')
    ->change();

that run okey but when delete it not set null:((

How I can solve that. Thank you!!

You must change your table migration schema in a new migration, and make sure you set the foreign key field as nullable:

$table->integer('wallet_id')->unsigned()->nullable();

and then use set null like this:

$table->...->onDelete('set null');

If you want to make changes to FOREIGN KEY Constraints first you need to drop the previous index of the foreign key and re add only Forign key Constraints to column.

Try this:

Schema::table('cards', function (Blueprint $table) {
            //Drop Previous Index
            $table->dropForeign('cards_wallet_id_foreign');

            //Since we want to set null on Delete Or Update
            $table->unsignedBigInteger('wallet_id')->nullable()->change();

            //Adding Only Forign key Constraints to column
            //calling foreignId will re attempt to create a column
            $table->foreign('wallet_id')->references('id')->on('wallets')->onDelete('set null')->onUpdate('set null')->change();

        });

You can not just modify the existing migration, You need to make another one

<?php
  
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
  
class ChangeSomeTableColumn extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('the_table_you_are_changing', function (Blueprint $table) {
            $table
                ->foreignId('wallet_id')
                ->constrained('wallets', 'id')
                ->onDelete('set null')
                ->change();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
          
    }
}

After collected and try many times I was found the best solution (don't need drop column)

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AlterWalletIdColumnInCardsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('cards', function (Blueprint $table) {
            $table->dropForeign('cards_wallet_id_foreign');
            $table->foreignId('wallet_id')
                ->nullable()
                ->change();

            $table->foreign('wallet_id')
                ->on('wallets')
                ->references('id')
                ->onDelete('set null');
        });
    }

    /**
     * I recommend you don't use down (laravel 9 will remove it as default 
     * migration)
     */
    public function down()
    {
        Schema::table('cards', function (Blueprint $table) {
            $table->dropForeign('cards_wallet_id_foreign');
            $table->foreignId('wallet_id')
                ->nullable(false)
                ->change();

            $table->foreign('wallet_id')
                ->on('wallets')
                ->references('id')
                ->onDelete('cascade');
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM