Заявление INSERT противоречит ограничениям внешнего ключа

Предыстория проекта: работа с интерфейсом пользователя MS-Access 2010 и задней панелью SQL Server 2008, которая хранит базу данных. Я пишу хранимые процедуры в SQL и запускаю их на SQL Server, а затем вызываю их в VBA из Access.

Когда нажата кнопка после получения необходимых значений и сохранения их в соответствующей переменной, я вызываю свою хранимую процедуру и передаю ей необходимые параметры. Желаемый эффект заключается в том, чтобы эти значения сохранялись в таблице tblFromICPMS. Но когда я нажимаю кнопку, я получаю сообщение об ошибке:

-2147217873 Оператор INSERT противоречил ограничению FOREIGN KEY "FK_tblFromICPMS_tblWOSampleTest". Конфликт произошел в базе данных "GSATest", таблица "dbo.tblWOSampleTest". в ImportICPMS

Я смотрел на вопросы людей с аналогичной проблемой, и большую часть времени проблема, похоже, лежит в их хранимой процедуре. Я не могу понять, что не так с моей хранимой процедурой и что конфликт может быть вызван.

При условии спецификации: В спецификации, которую я получил, мне был предоставлен код SQL, чтобы сделать таблицу (TblFromICPMS) с помощью внешних ключей.

Вот сценарий для этого:

IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo]. [FK_tblFromICPMS_tblWOSampleTest]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblFromICPMS]')) ALTER TABLE [dbo].[tblFromICPMS] DROP CONSTRAINT [FK_tblFromICPMS_tblWOSampleTest]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[DF_tblFromICPMS_DateImported]') AND type = 'D')
BEGIN ALTER TABLE [dbo].[tblFromICPMS] DROP CONSTRAINT [DF_tblFromICPMS_DateImported]
END
GO
/****** Object: Table [dbo].[tblFromICPMS] Script Date: 5/14/2014 9:29:33 AM ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tblFromICPMS]') AND type in (N'U')) DROP TABLE [dbo].[tblFromICPMS]
GO
/****** Object: Table [dbo].[tblFromICPMS] Script Date: 5/14/2014 9:29:33 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tblFromICPMS]') AND type in (N'U'))
BEGIN CREATE TABLE [dbo].[tblFromICPMS] (
[FromICPMSID] [int] IDENTITY(1,1) NOT NULL,
[Sample Name] [nvarchar](255) NULL,
[Date And Time Acquired] [nvarchar](255) NULL,
[Analyte] [nvarchar](20) NULL,
[Concentration] [nvarchar](255) NULL,
[Units] [nvarchar](255) NULL,
[DateImported] [datetime] NOT NULL,
[DateAnalyzed] [datetime] NULL,
[BatchID] [int] NOT NULL,
[QueueID] [int] NULL,
[WOID] [nvarchar](10) NULL,
[SampleID] [int] NULL,
[TestID] [int] NULL,
[ActResult] [float] NULL,
[Issue] [nvarchar](255) NULL,
CONSTRAINT [PK_tblFromICPMS] PRIMARY KEY CLUSTERED ([FromICPMSID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo]. [DF_tblFromICPMS_DateImported]') AND type = 'D')
BEGIN ALTER TABLE [dbo].[tblFromICPMS] ADD CONSTRAINT [DF_tblFromICPMS_DateImported] DEFAULT (getdate()) FOR [DateImported]
END
GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo]. [FK_tblFromICPMS_tblWOSampleTest]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblFromICPMS]')) ALTER TABLE [dbo].[tblFromICPMS] WITH CHECK ADD CONSTRAINT [FK_tblFromICPMS_tblWOSampleTest] FOREIGN KEY([WOID], [SampleID], [TestID]) REFERENCES [dbo].[tblWOSampleTest] ([WOID], [SampleID], [TestID])
GO
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tblFromICPMS_tblWOSampleTest]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblFromICPMS]')) ALTER TABLE [dbo].[tblFromICPMS] CHECK CONSTRAINT [FK_tblFromICPMS_tblWOSampleTest]
GO

И вот сценарий для моей хранимой процедуры:

CREATE PROCEDURE upInsertFromICPMSRecord @SampleName nvarchar(60), @DateTimeAcquired nvarchar(60), @Analyte nvarchar(60), @Concentration nvarchar(60), @QueueID nvarchar(60), @Units nvarchar(60), @ThisWOID nvarchar(60), @ThisSampleID nvarchar(60), @ThisTestID nvarchar(60), @ActResult nvarchar(60), @Issue nvarchar(60), @BatchID nvarchar(60)
AS INSERT INTO tblFromICPMS ("Sample Name","Date And TimeAcquired",Analyte,concentration,Units,DateImported,DateAnalyzed,BatchID, QueueID, WOID, SampleID, TestID, ActResult, Issue) VALUES (@SampleName, @DateTimeAcquired, @Analyte, @Concentration, @Units, getdate(), CONVERT(datetime, @DateTimeAcquired), @BatchID, @QueueID, @ThisWOID, @ThisSampleID, @ThisTestID, @ActResult, @Issue);
GO

Для некоторого дополнительного фона другой хранимой процедурой, которую я должен был сделать, был GetTestIdForAnalyte который в основном тестировался, чтобы проверить, существует ли TESTID для конкретного обрабатываемого файла. Он имеет выходной параметр, который хранит количество затронутых строк. Поэтому, если он больше нуля, я знаю, что существует TestID. Я работаю над тестовой базой данных, и файлы, над которыми я работаю, не входят в систему, поэтому testID никогда не будет существовать. Я не знаю, вызывает ли это проблему, но для этого здесь хранится процедура.

CREATE PROCEDURE upGetTestIDForAnalyte @WOID nvarchar(60), @SampleID nvarchar(60), @Analyte nvarchar(60), @RecordsAffected int OUT
AS SELECT TestID = t1.TestID FROM tblWOSampleTest t1 JOIN tblTest t2 ON t1.TestID = t2.TestID; WHERE @WOID = t1.WOID AND @SampleID = t1.SampleID AND @Analyte = t2.Analyte SET @RecordsAffected = @@ROWCOUNT
GO

Если есть TestID я могу продолжить и вставить записи, вызвав мою другую хранимую процедуру, иначе я вставляю сообщение об ошибке в журнал ошибок. Я просто проигнорировал это ради тестирования, потому что думал, что это не имеет значения.

1 ответ

Это в основном просто ограничение, tblFromICPMS то, что вы пытаетесь вставить запись в tblFromICPMS, у которой нет соответствующей записи в tblWOSampleTest с тем же WOID, SampleID и TestID.

При наличии ограничения, вы ДОЛЖНЫ иметь запись в tblWOSampleTest с этими значениями, tblWOSampleTest чем вы сможете вставлять их в tblFromICPMS - вот что такое ограничение феодального ключа.

http://www.w3schools.com/sql/sql_foreignkey.asp

licensed under cc by-sa 3.0 with attribution.