Framework: Disable ForeignKeyConstraints not working with SQL Server

Created on 28 Nov 2020  路  4Comments  路  Source: laravel/framework

  • Laravel Version: 8.16.1
  • PHP Version: 7.4
  • Database Driver & Version: ODBC Driver 17 For SQL Server

Description:

I'm trying to truncate a table before seed and i use the following code

Schema::disableForeignKeyConstraints();
DB::table('tableName')->truncate();
Schema::enableForeignKeyConstraints();

The error that i receive is:

 SQLSTATE[42000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server] Cannot truncate a table referenced in a foreign key constraint. (SQL: truncate table [tablename])
help wanted needs more info

All 4 comments

Will need help from someone which can test this on SQL Server with the ODBC driver.

Per MSDN docs on TRUNCATE TABLE

You cannot use TRUNCATE TABLE on tables that:

  • Are referenced by a FOREIGN KEY constraint. You can truncate a table that has a foreign key that references itself.

Reference: https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-ver15#restrictions

SQL Server won't let you truncate a table that have foreign keys constraints referencing it.

The catch here is that even when the foreign key constraints checks are disabled, the foreign keys references are still there.

Disabling the checks is the same as telling SQL Server: "hey don't bother with them, we both know they are still there, but ignore them for a while". It works for DML commands where SQL looks at the data being manipulated.

But TRUNCATE TABLE is a DDL command. SQL Server won't look to the related table records, it will check the table definition and the database schema before running it. If there are foreign keys referencing that table, it will fail.

If you really need to truncate, mostly for performance reasons, for example when you have a huge table, you'll need to drop the foreign keys, truncate and then recreate those.

Another option is to use DB::table('tableName')->delete(); instead, but I know it can be much slower.

I found some threads in Stack Overflow with alternative solutions, such as making a script to drop all foreign keys and recreate them later:

https://stackoverflow.com/a/253931/1211472

https://stackoverflow.com/a/3843826/1211472

Unfortunately there is not much to do on Laravel side.

Hope this helps.

Thanks for the help here (again) @rodrigopedra :)

You鈥檙e welcome @driesvints ! Have a nice day =)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

klimentLambevski picture klimentLambevski  路  3Comments

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

felixsanz picture felixsanz  路  3Comments

JamborJan picture JamborJan  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments