Я очень новичок с SQL, и я борюсь с проблемой, на которую не могу найти ответ. Я нашел подобные вопросы здесь о переполнении стека, но я все еще не вижу, что я должен изменить в своем коде, чтобы заставить его работать.
У меня есть 4 таблицы в отношении следующим образом:
CREATE TABLE DeviceLocation (
LocationId int not null identity(1,1) primary key,
Latitude nvarchar(50) not null,
Longitude nvarchar(50) not null
)
GO
CREATE TABLE TempHumidSensor (
TempHumidSensorId int not null identity(1,1) primary key,
Humidity float not null,
Temperature float not null
)
GO
CREATE TABLE LightSensor (
LightSensorId int not null identity(1,1) primary key,
LightPercentage int not null
)
GO
CREATE TABLE DeviceMessage (
MessageId nvarchar(50) not null primary key,
DeviceId nvarchar(20) not null,
temperatureAlert nvarchar(20) not null,
institutionClassName nvarchar(20) not null,
institutionName nvarchar(20) not null,
developerName nvarchar(20) not null,
MessageTimestamp nvarchar(20) not null,
TempSensorId int not null references TempHumidSensor(TempHumidSensorId),
LightSensorId int not null references LightSensor(LightSensorId),
DeviceLocationId int not null references DeviceLocation(LocationId)
)
GO
Затем у меня есть три процедуры, которые возвращают первичный ключ значения идентификатора для DeviceLocation , TempHumidSensor , LightSensor перед вставкой в DeviceMessage , следующим образом:
GetDeviceLocation
ALTER procedure [dbo].[GetDeviceLocation]
@Latitude nvarchar(50),
@Longitude nvarchar(50)
as
begin
if not exists (select 1 from DeviceLocation where Latitude = @Latitude and Longitude = @Longitude)
insert into DeviceLocation output inserted.LocationId values (@Latitude, @Longitude)
else
select LocationId from DeviceLocation where Latitude = @Latitude and Longitude = @Longitude
end
GetLightSensor
ALTER procedure [dbo].[GetLightSensor]
@LightPercentage int
as
begin
if not exists (select 1 from LightSensor where LightPercentage = @LightPercentage)
insert into LightSensor output inserted.LightSensorId values (@LightPercentage)
else
select LightSensorId from LightSensor where LightPercentage = @LightPercentage
end
GetTempHumidSensor
ALTER procedure [dbo].[GetTempHumidSensor]
@Humidity float,
@Temperature float
as
begin
if not exists (select 1 from TempHumidSensor where Humidity = @Humidity and Temperature = @Temperature)
insert into TempHumidSensor output inserted.TempHumidSensorId values (@Humidity, @Temperature)
else
select TempHumidSensorId from TempHumidSensor where Humidity = @Humidity and Temperature = @Temperature
end
Наконец, есть процедура SaveSqlData , которая вызывается кодом. NET в конце.
ALTER PROCEDURE [dbo].[SaveSqlData]
@Latitude NVARCHAR(50),
@Longitude NVARCHAR(50),
@Humidity FLOAT,
@Temperature FLOAT,
@LightPercentage INT,
@MessageTimestamp NVARCHAR(20),
@MessageId NVARCHAR(50),
@DeviceId NVARCHAR(20),
@temperatureAlert NVARCHAR(20),
@institutionClassName NVARCHAR(20),
@institutionName NVARCHAR(20),
@developerName NVARCHAR(20)
AS
BEGIN
DECLARE @DeviceLocationId INT,
@TempHumidSensorId INT,
@LightSensorId INT
EXEC @TempHumidSensorId = GetTempHumidSensor @Humidity = @Humidity, @Temperature = @Temperature
EXEC @LightSensorId = GetLightSensor @LightPercentage = @LightPercentage
EXEC @DeviceLocationId = GetDeviceLocation @Latitude = @Latitude, @Longitude = @Longitude
INSERT INTO dbo.DeviceMessage(
MessageId,
DeviceId,
temperatureAlert,
institutionClassName,
institutionName,
developerName,
MessageTimestamp,
TempHumidSensorId,
DeviceLocationId,
LightSensorId
)
VALUES (
@MessageId,
@DeviceId,
@temperatureAlert,
@institutionClassName,
@institutionName,
@developerName,
@MessageTimestamp,
@TempHumidSensorId,
@DeviceLocationId,
@LightSensorId
)
END
Обычно я проверяю эту процедуру с помощью следующего фрагмента:
exec dbo.SaveSqlData
@Latitude = '55.5555',
@Longitude = '66.6666',
@Humidity = 41.2,
@Temperature = 25.0,
@LightPercentage = 91,
@MessageTimestamp = 123123123,
@temperatureAlert = 'false',
@MessageId = 'sd344d3j-guid-mock-124-123',
@DeviceId = 'device-name-from-device',
@institutionClassName = 'class',
@developerName = 'test',
@institutionName = 'institution'
Ошибка, которая отображается как при вызове этого метода из C#, так и при выполнении указанного выше теста: 1041 *
(1 row affected)
(1 row affected)
(1 row affected)
Msg 547, Level 16, State 0, Procedure dbo.SaveSqlData, Line 27 [Batch Start Line 0]
The INSERT statement conflicted with the FOREIGN KEY constraint "FK__DeviceMes__TempH__11D4A34F". The conflict occurred in database "telemetry-sqldb", table "dbo.TempHumidSensor", column 'TempHumidSensorId'.
The statement has been terminated.
Я читал, что это связано с порядком вставок, но я не уверен, как это исправить или где именно проблема заключается.
Я вижу, что при возникновении этой ошибки есть вставки во все таблицы, кроме DeviceMessage. Любая помощь очень ценится.