2014-10-09 12 views
1

У меня есть 2 таблицы:SQL Server DateTimeOffset составного ключа

Vehicles: 
Id (int,PK), 
PositionTime (datetimeoffset) 
Positions: 
Accuracy (int), 
VehicleId (int) 
TimeLocal (datetimeoffset)(VehicleId and TimeLocal are composite PK pointing to Id and PositionTime in Vehicles) 

Я хочу, чтобы обновить все даты до сегодняшнего дня (время остается неизменным) в обеих таблицах (это означает, что связь между таблицами обновит слишком). Я попытался сначала обновить Позиции, затем Транспортные средства. Но я получаю ошибку:

Violation of PRIMARY KEY constraint 'PK_Positions'. Cannot insert duplicate key in object 'dbo.Positions'. 

Дубликат значение ключа (1, 2014-10-09 16: 13: 50,0000000 +03: 00). Глядя в позиции, в таблице «Позиции» есть только одно значение «1,2014-04-24 16: 13: 50.0000000 +03: 00». Реализация в настоящее время:

UPDATE 
[dbo].[Positions] 
SET 
[dbo].[Positions].TimeLocal = CONVERT(DATETIMEOFFSET, DATETIMEOFFSETFROMPARTS(datepart(yyyy, @date), datepart(mm, @date), datepart(dd, @date), datepart(HH, [dbo].[Positions].TimeLocal), datepart(MI, [dbo].[Positions].TimeLocal), datepart(SS, [dbo].[Positions].TimeLocal), datepart(MILLISECOND, [dbo].[Positions].TimeLocal), CAST((FLOOR(DATEPART(TZ, [dbo].[Positions].TimeLocal))/60) AS VARCHAR(10)), CAST((DATEPART(TZ,[dbo].[Positions].TimeLocal)%60) AS VARCHAR(10)), 3)) 
FROM 
[dbo].[Positions] 
INNER JOIN 
[dbo].[Vehicles] 
ON 
[dbo].[Positions].VehicleId = [dbo].[Vehicles].Id 

спасибо !! Added DB relationship for clarity

ответ

0

Я немного смущен вашей схемой базы данных, но я предполагаю, что это что-то вроде ниже (полезно, если вы можете включить dml и настроить данные в будущем).

-- Create tables 
CREATE TABLE [dbo].[Vehicle](
    [Id] [int] NOT NULL, 
    [PositionTime] [datetimeoffset](7) NOT NULL, 
CONSTRAINT [PK__Vehicle__3214EC070A607A7B] PRIMARY KEY CLUSTERED 
( [Id] ASC, 
    [PositionTime] ASC) ) ON [PRIMARY] 
GO 


CREATE TABLE [dbo].[Position](
    [VehicleId] [int] NOT NULL, 
    [LocalTime] [datetimeoffset](7) NOT NULL, 
    [Accuracy] [int] NOT NULL, 
CONSTRAINT [PK_Position] PRIMARY KEY CLUSTERED 
( [Accuracy] ASC) ) ON [PRIMARY] 
GO 

ALTER TABLE [dbo].[Position] WITH CHECK ADD CONSTRAINT [FK_Position_Vehicle] FOREIGN KEY([VehicleId], [LocalTime]) 
REFERENCES [dbo].[Vehicle] ([Id], [PositionTime]) ON UPDATE CASCADE 
GO 

ALTER TABLE [dbo].[Position] CHECK CONSTRAINT [FK_Position_Vehicle] 
GO 

-- Load data 
INSERT INTO Vehicle VALUES(1, '2014-01-01 01:01:01.6660000 +01:00') 
INSERT INTO Vehicle VALUES(2, '2014-01-02 01:01:01.6660000 +01:00') 
INSERT INTO Vehicle VALUES(3, '2014-01-03 01:01:01.6660000 +01:00') 
INSERT INTO Vehicle VALUES(4, '2014-01-04 01:01:01.6660000 +01:00') 
INSERT INTO Vehicle VALUES(5, '2014-01-05 01:01:01.6660000 +01:00') 

INSERT INTO Position VALUES(1, '2014-01-01 01:01:01.6660000 +01:00',1) 
INSERT INTO Position VALUES(2, '2014-01-02 01:01:01.6660000 +01:00',2) 
INSERT INTO Position VALUES(3, '2014-01-03 01:01:01.6660000 +01:00',3) 
INSERT INTO Position VALUES(4, '2014-01-04 01:01:01.6660000 +01:00',4) 
INSERT INTO Position VALUES(5, '2014-01-05 01:01:01.6660000 +01:00',5) 
GO 

Обратите внимание, что код ON UPDATE CASCADE находится на внешнем ключе в таблице позиций. Это позволяет отражать изменения в таблице ссылок в таблице реферера. См. Выше. Ниже я включил оператор обновления, чтобы изменить локальный столбец времени и упростить создание тайм-кода sql.

-- Before update 
SELECT * FROM Vehicle 
SELECT * FROM Position 

UPDATE Vehicle 
SET  PositionTime = DATEADD(DAY, DATEDIFF(DAY, DATEADD(DAY, DATEDIFF(DAY, 0, PositionTime), 0), CAST(GETDATE() AS DATE)), PositionTime) 

-- After update 
SELECT * FROM Vehicle 
SELECT * FROM Position 

Надеюсь, это поможет.

+0

Это правда, что я был недостаточно ясен. Отношение находится в связанном изображении: [link] (https://drive.google.com/file/d/0B-WyYs74In7seHNfa0tqRlZNVkk/view?usp=sharing). Ваш ответ действительно близок к тому, что мне нужно. – user3546827

+0

Какое решение я предложил не тем, что вы ищете? На приведенной диаграмме показаны два внешних ключа от позиции до автомобиля на VehiceId до Id и TimeLocal до PositionTime. Возможно, у меня начальная настройка немного неточна, но если вы примените ON UPDATE CASCADE к внешнему ключу DateTimeOffset и обновите данные в первичной таблице, данные, измененные в таблице транспортных средств, будут каскадированы до таблицы позиций. – Steve

Смежные вопросы