Конфликт инструкции delete с ограничением reference sql

I tried to truncate a table with foreign keys and got the message:

«Cannot truncate table because it is being referenced by a FOREIGN KEY constraint«.

I read a lot of literature about the problem and thought that I found the solution by using delete

DELETE FROM table_name DBCC CHECKIDENT (table_name, RESEED, 0)

But I still got an error message:

«The DELETE statement conflicted with the REFERENCE constraint«.

When I try to delete with Microsoft Management Studio and execute the previous query

DELETE FROM table_name DBCC CHECKIDENT (table_name, RESEED, 0)

it doesn’t give an error and works properly. I want to delete all information from a table and add new into it, but I don’t want to drop and create foreign keys.

Rob's user avatar

Rob

27k16 gold badges82 silver badges98 bronze badges

asked Sep 23, 2010 at 7:42

Peter's user avatar

The error means that you have data in other tables that references the data you are trying to delete.

You would need to either drop and recreate the constraints or delete the data that the Foreign Key references.

Suppose you have the following tables

dbo.Students
(
StudentId
StudentName
StudentTypeId
)


dbo.StudentTypes
(
StudentTypeId
StudentType
)

Suppose a Foreign Key constraint exists between the StudentTypeId column in StudentTypes and the StudentTypeId column in Students

If you try to delete all the data in StudentTypes an error will occur as the StudentTypeId column in Students reference the data in the StudentTypes table.

EDIT:

DELETE and TRUNCATE essentially do the same thing. The only difference is that TRUNCATE does not save the changes in to the Log file. Also you can’t use a WHERE clause with TRUNCATE

AS to why you can run this in SSMS but not via your Application. I really can’t see this happening. The FK constraint would still throw an error regardless of where the transaction originated from.

answered Sep 23, 2010 at 7:50

codingbadger's user avatar

codingbadgercodingbadger

42.7k13 gold badges95 silver badges111 bronze badges

4

Have you considered applying ON DELETE CASCADE where relevant?

answered Sep 23, 2010 at 9:56

annakata's user avatar

annakataannakata

74.6k18 gold badges114 silver badges180 bronze badges

You are trying to delete a row that is referenced by another row (possibly in another table).

You need to delete that row first (or at least re-set its foreign key to something else), otherwise you’d end up with a row that references a non-existing row. The database forbids that.

answered Sep 23, 2010 at 7:46

Konrad Rudolph's user avatar

Konrad RudolphKonrad Rudolph

531k133 gold badges939 silver badges1215 bronze badges

1

To DELETE, without changing the references, you should first delete or otherwise alter (in a manner suitable for your purposes) all relevant rows in other tables.

To TRUNCATE you must remove the references. TRUNCATE is a DDL statement (comparable to CREATE and DROP) not a DML statement (like INSERT and DELETE) and doesn’t cause triggers, whether explicit or those associated with references and other constraints, to be fired. Because of this, the database could be put into an inconsistent state if TRUNCATE was allowed on tables with references. This was a rule when TRUNCATE was an extension to the standard used by some systems, and is mandated by the the standard, now that it has been added.

answered Sep 23, 2010 at 9:51

Jon Hanna's user avatar

Jon HannaJon Hanna

111k10 gold badges147 silver badges251 bronze badges

In SQL server
go to the database diagram and choose relation properties
go to insert and update Specification column
make the delete rule set to null

answered Dec 7, 2022 at 23:43

Mohamed Sami Khiari's user avatar

I also ran into this issue, and I was able to resolve it. Here is my situation:

In my case, I have a database used for reporting an analytics (MYTARGET_DB), which pulls from a source system (MYSOURCE_DB). Some of the ‘MYTARGET_DB’ tables are unique to that system, and data is created & managed there; Most of the tables are from ‘MYSOURCE_DB’ and there is a job that deletes/ inserts the data into ‘MYTARGET_DB’ from ‘MYSOURCE_DB’.

One of the lookup tables [PRODUCT] is from the SOURCE, and there is a data table [InventoryOutsourced] stored in the TARGET. There is referential integrity designed into the tables. So when I try to run the delete/insert I get this message.

Msg 50000, Level 16, State 1, Procedure uspJobInsertAllTables_AM, Line 249
The DELETE statement conflicted with the REFERENCE constraint "FK_InventoryOutsourced_Product". The conflict occurred in database "ProductionPlanning", table "dbo.InventoryOutsourced", column 'ProdCode'.

The workaround I created is to insert data into [@tempTable] table variable from [InventoryOutsourced], delete data in [InventoryOutsourced], run the synch jobs, insert into [InventoryOutsourced] from [@tempTable]. This keeps the integrity in place, and the unique data collection is also retained. Which is the best of both worlds. Hope this helps.

BEGIN TRY
    BEGIN TRANSACTION InsertAllTables_AM

        DECLARE
        @BatchRunTime datetime = getdate(),
        @InsertBatchId bigint
            select @InsertBatchId = max(IsNull(batchid,0)) + 1 from JobRunStatistic 

        --<DataCaptureTmp/> Capture the data tables unique to this database, before deleting source system reference tables
            --[InventoryOutsourced]
            DECLARE @tmpInventoryOutsourced as table (
                [ProdCode]      VARCHAR (12)    NOT NULL,
                [WhseCode]      VARCHAR (4)     NOT NULL,
                [Cases]          NUMERIC (8)     NOT NULL,
                [Weight]         NUMERIC (10, 2) NOT NULL,
                [Date] DATE NOT NULL, 
                [SourcedFrom] NVARCHAR(50) NOT NULL, 
                [User] NCHAR(50) NOT NULL, 
                [ModifiedDatetime] DATETIME NOT NULL
                )

            INSERT INTO @tmpInventoryOutsourced (
                [ProdCode]
               ,[WhseCode]
               ,[Cases]
               ,[Weight]
               ,[Date]
               ,[SourcedFrom]
               ,[User]
               ,[ModifiedDatetime]
               )
            SELECT 
                [ProdCode]
                ,[WhseCode]
                ,[Cases]
                ,[Weight]
                ,[Date]
                ,[SourcedFrom]
                ,[User]
                ,[ModifiedDatetime]
            FROM [dbo].[InventoryOutsourced]

            DELETE FROM [InventoryOutsourced]
        --</DataCaptureTmp> 

... Delete Processes
... Delete Processes    

        --<DataCaptureInsert/> Capture the data tables unique to this database, before deleting source system reference tables
            --[InventoryOutsourced]
            INSERT INTO [dbo].[InventoryOutsourced] (
                [ProdCode]
               ,[WhseCode]
               ,[Cases]
               ,[Weight]
               ,[Date]
               ,[SourcedFrom]
               ,[User]
               ,[ModifiedDatetime]
               )
            SELECT 
                [ProdCode]
                ,[WhseCode]
                ,[Cases]
                ,[Weight]
                ,[Date]
                ,[SourcedFrom]
                ,[User]
                ,[ModifiedDatetime]
            FROM @tmpInventoryOutsourced
            --</DataCaptureInsert> 

    COMMIT TRANSACTION InsertAllTables_AM
END TRY

  • Remove From My Forums
  • Вопрос

  • Доброго дня коллеги !
    Сразу скажу , что в чайник в SQL, заранее прошу прощения поэтому.

    В общем дело такое..
    Я удалил каким то образом некорректно задание или план обсуживания , что он остался висеть и теперь я удалить не могу , пишет ошибк.

    Я командой SELECT NAME, ID FROM MSDB..SYSMAINTPLAN_PLANS узнал какой ИД у этого задания …

    А дальше не знаю точно, что делать , можете подсказать ?

    Хотя я так в целом понимаю , что проблема не критична , но все же хотелось бы удалить ..

    Лог при удалении Задания:

    ЗАГОЛОВОК: Microsoft SQL Server Management Studio
    ——————————

    Не удалось выполнить действие «Удалить» для следующего объекта: «Задание», «очистка лога.ВложенныйПлан_1». (Microsoft.SqlServer.Smo)

    ——————————
    ДОПОЛНИТЕЛЬНЫЕ СВЕДЕНИЯ:

    При выполнении инструкции или пакета Transact-SQL возникло исключение. (Microsoft.SqlServer.ConnectionInfo)

    ——————————

    Конфликт инструкции DELETE с ограничением REFERENCE «FK_subplan_job_id». Конфликт произошел в базе данных «msdb», таблица «dbo.sysmaintplan_subplans», column ‘job_id’.
    Выполнение данной инструкции было прервано. (Microsoft SQL Server, ошибка: 547)

    Лог удаления плана обслуживания :

    ЗАГОЛОВОК: Microsoft SQL Server Management Studio
    ——————————

    Адресат вызова создал исключение. (mscorlib)

    ——————————
    ДОПОЛНИТЕЛЬНЫЕ СВЕДЕНИЯ:

    Индекс за пределами диапазона. Индекс должен быть положительным числом, а его размер не должен превышать размер коллекции.
    Имя параметра: index (mscorlib)

    Версия скуля

    Microsoft SQL Server Management Studio 13.0.16106.4
    Клиентские средства служб Microsoft Analysis Services 13.0.1700.441
    Компоненты доступа к данным (MDAC) 10.0.14393.0
    Microsoft MSXML 3.0 6.0
    Microsoft Internet Explorer 9.11.14393.0
    Microsoft .NET Framework 4.0.30319.42000
    Операционная система 6.3.14393

    Очень рассчитываю на вас!

    Я так понял нужно было удалять задание из «плана обслуживания» ,а не из агента …

    • Изменено

      7 мая 2018 г. 13:12

Ответы

  • В общем , задача оказалось простой , но поскольку я баран , ушло на это пол дня )

    Вот решение)
    В инете кстати толком нет инфы, видимо задача на столько изи , что ее никто не описывает.

    1. Пишем этот запрос :select * from msdb.dbo.sysmaintplan_plans — он нам даст нужный ИД убитого задания.

    2. далее пишем эти команды и все
    delete from msdb.dbo.sysmaintplan_subplans where plan_id = »
    delete from msdb.dbo.sysmaintplan_plans where id = »

    • Помечено в качестве ответа
      Cognos11
      8 мая 2018 г. 12:38

I’m trying to delete all users but getting the error:

Msg 547, Level 16, State 0, Line 1
The DELETE statement conflicted with the REFERENCE constraint "FK_M02ArticlePersons_M06Persons". The conflict occurred in database "workdemo.no", table "dbo.M02ArticlePersons", column 'M06PersonId'.
The statement has been terminated.

The query:

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
WHERE ID > '13'
GO

Seems I need to use on delete cascade; but I’m stuck.

Mark Storey-Smith's user avatar

asked Apr 4, 2013 at 11:50

Darkmage's user avatar

You don’t need to use the on delete cascade. Somebody (the schema design author) had made sure you cannot delete a person that is still referenced by an article. It succeeded, you were just trying to do this and was blocked, kudos to the designer.

Now go and talk with that somebody that designed the schema and knows the constraints and ask him how to properly delete the records you’re trying to delete, in the correct order and taking the proper precautions to keep the database consistent.

Community's user avatar

answered Apr 4, 2013 at 12:02

Remus Rusanu's user avatar

Remus RusanuRemus Rusanu

51.6k3 gold badges94 silver badges172 bronze badges

You have two real choices here, you can disable constraints on the table. This usually not a great idea as you can end up with a bad data condition if you’re messing with data that relates to other tables, but not know the full extent of your schema and it may suit your purposes:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] NOCHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

Remember to turn the constraint back on after the delete with

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH CHECK CHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

The second choice would be to drop and re-add the constraint with the ON DELETE CASCADE option using:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] DROP CONSTRAINT [FK_M02ArticlePersons_M06Persons]

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH NOCHECK ADD CONSTRAINT [FK_M02ArticlePersons_M06Persons] FOREIGN KEY(M06PersonId)
REFERENCES <parent table here> (<parent column here>)
ON DELETE CASCADE

Based on your FK name it looks like your parent table is M02ArticlePersons and the parent column is M06Persons.

If you did not author this schema please try to consider why the constraints may be present, and understand that violating them in this manner may have unintended side effects.

answered Apr 4, 2013 at 12:10

Ahrotahntee's user avatar

0

dbo.M02ArticlePersons table of column M06PersonId is reffered in another table.
So before delete statement, disable this relationships and try again

below is for disbling the foreign key

 ALTER TABLE dbo.M02ArticlePersons NOCHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
  WHERE ID > '13'
GO

and this is to enable it

ALTER TABLE dbo.M02ArticlePersons CHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

Hope this will work

answered Apr 4, 2013 at 12:04

Navin 431's user avatar

1

There is another manual option too:

You can go to the child table and delete the child rows referenced by the parent key. Then you can delete the parent row. This is essentially what the cascade delete does. This way, you do not have to drop/recreate/alter your constraints.

answered Apr 4, 2013 at 14:49

StanleyJohns's user avatar

StanleyJohnsStanleyJohns

5,9422 gold badges21 silver badges44 bronze badges

This little code will help for any table that you want to delete records from. It takes care of referential integrity as well …

Below code will generate DELETE statements .. Just specify the schema.table_Name

Declare @sql1 varchar(max)
      , @ptn1 varchar(200)
      , @ctn1 varchar(200)
      , @ptn2 varchar(200)
      , @ctn2 varchar(200)
--
SET @ptn1 = ''
--
SET @ctn1 = ''
--
SET @ptn2 = ''
--
SET @ctn2 = ''
--
SELECT @sql1 = case when (@ptn1 <> OBJECT_NAME (f.referenced_object_id)) then
                         COALESCE( @sql1 + char(10), '') + 'DELETE' + char(10) + ' ' + OBJECT_NAME (f.referenced_object_id) + ' FROM ' + OBJECT_NAME(f.parent_object_id) + ', '+OBJECT_NAME (f.referenced_object_id) + char(10) +' WHERE ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    else
                         @sql1 + ' AND ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    end + char(10)
     , @ptn1 = OBJECT_NAME (f.referenced_object_id)
     , @ptn2  = object_name(f.parent_object_id)
FROM   sys.foreign_keys AS f
       INNER JOIN
       sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
WHERE  f.parent_object_id = OBJECT_ID('dbo.M06Persons'); -- CHANGE here schema.table_name
--
print  '--Table Depended on ' + @ptn2 + char(10) + @sql1

answered Apr 4, 2013 at 19:56

Kin Shah's user avatar

Kin ShahKin Shah

62k6 gold badges119 silver badges235 bronze badges

You are trying to Delete the record from a Table which has a reference in another Table.

Here REFERENCE constraint is «FK_User_History_Tbl_Customer«.

Tables are User_History and Tbl_Customer.
UserId column is referenced by Tbl_Customer Table.

When you try to delete a row from User_History Table, it comes to know that the same row has some related row in Tbl_Customer Table.

So, you need to delete from Tbl_Customer Table first and then delete from Table User_History.

If you want to delete a row, then you have to execute the following two queries in sequence.

DELETE FROM Tbl_Customer
WHERE UserId = [[[UserIdToDelete]]];

DELETE FROM User_History
WHERE UserId = [[[UserIdToDelete]]]

Понравилась статья? Поделить с друзьями:
  • Модульное оригами вечный огонь пошаговая инструкция
  • Инструкция по заполнению формы сзв стаж
  • Как оплатить классное руководство
  • Руководство соревнований по волейболу
  • Должностная инструкция преподавателя организатора обж по профстандарту 2021