2014-10-09 65 views
1

我有2個表:SQL服務器更新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月9日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 2014-10-09 15:12:04

+0

我提出的解決方案不是你想要的?您提供的圖表顯示了從Position到Vehicle的VehiceId到Id和TimeLocal到PositionTime的兩個外鍵。我可能已經將初始設置稍微不準確,但如果將ON UPDATE CASCADE應用於DateTimeOffset外鍵並更新主表中的數據,則車輛表中修改的數據將級聯到位置表。 – Steve 2014-10-09 15:23:30