我有一個應該轉換爲一個目標表的源表。源表包含四個帶有傳感器值的列。目的地表格應包含四行,一行傳感器值,一行傳感器編號 - 源表格中的每一行。換句話說,目標表將有四倍多的行。 (我相信這被稱爲標準化,至少,我認爲未來將會使用更多或更少的或不同的傳感器時更實際)。將一行分割成更多行 - 錶轉換
更多背景信息來解釋。我已經成功地嘗試一個INSERT觸發器,做,對於單行:
CREATE TRIGGER dbo.temperatures_to_sensors
ON dbo.Data
AFTER INSERT
AS
BEGIN
DECLARE @line_no TINYINT;
SET @line_no = 2; -- hardwired for the production line
DECLARE @UTC DATETIME;
DECLARE @value1 FLOAT;
DECLARE @value2 FLOAT;
DECLARE @value3 FLOAT;
DECLARE @value4 FLOAT;
SELECT
@UTC = CAST((CAST(LEFT(inserted.UTC, 16) AS FLOAT) - 2415020.5) AS DATETIME),
@value1 = inserted.temperature_1,
@value2 = inserted.temperature_2,
@value3 = inserted.temperature_3,
@value4 = inserted.temperature_4
FROM inserted;
INSERT INTO dbo.line_sensor_values
(UTC, line_no, sensor_no, sensor_value)
VALUES (@UTC, @line_no, 1, @value1),
(@UTC, @line_no, 2, @value2),
(@UTC, @line_no, 3, @value3),
(@UTC, @line_no, 4, @value4);
END;
GO
現在,我想從舊錶初始化目標表一次。之後,觸發器將繼續填充值。我的SQL不好。我想:
CREATE PROCEDURE dbo.init_line_sensor_values
AS
BEGIN
DECLARE @line_no TINYINT;
SET @line_no = 2; -- hardwired for the production line
DECLARE @UTC DATETIME;
DECLARE @value1 FLOAT;
DECLARE @value2 FLOAT;
DECLARE @value3 FLOAT;
DECLARE @value4 FLOAT;
INSERT INTO dbo.line_sensor_values
(UTC, line_no, sensor_no, sensor_value)
VALUES (@UTC, @line_no, 1, @value1),
(@UTC, @line_no, 2, @value2),
(@UTC, @line_no, 3, @value3),
(@UTC, @line_no, 4, @value4)
SELECT
@UTC = CAST((CAST(LEFT(t.UTC, 16) AS FLOAT) - 2415020.5) AS DATETIME),
@value1 = t.temperature_1,
@value2 = t.temperature_2,
@value3 = t.temperature_3,
@value4 = t.temperature_4
FROM dbo.Data AS t;
END;
GO
EXECUTE dbo.init_line_sensor_values
GO
...但它失敗
無法將NULL值插入列 'UTC',表 '1000574.dbo.line_sensor_values';列不允許有空值。 INSERT失敗。
很明顯SELECT
應該用不同的方式填入INSERT
。或者我必須使用循環? (光標創建和FETCH NEXT...
和WHILE...
)
修訂
源表可以創建這樣(簡化):
CREATE TABLE dbo.Data(
UTC varchar(32) NOT NULL,
temperature_1 float NULL,
temperature_2 float NULL,
temperature_3 float NULL,
temperature_4 float NULL
PRIMARY KEY CLUSTERED
(
UTC ASC
)
GO
目標表創建這樣:
CREATE TABLE dbo.line_sensor_values (
UTC DATETIME NOT NULL,
line_no TINYINT NOT NULL, -- line number: 1, 2, 3, etc.
sensor_no TINYINT NOT NULL, -- sensor number: 1, 2, 3, etc.
sensor_value float NULL, -- the measured value
PRIMARY KEY CLUSTERED (
UTC ASC,
line_no ASC,
sensor_no ASC
)
)
GO
感謝您的幫助,Petr
您可以張貼表DDL語句? – Taryn 2012-08-09 21:34:37
你的問題是創建一個有四行的表格,一行四列。爲什麼不一次性將值插入表中?寫入的代碼量表示爲小問題付出了大量努力。 – 2012-08-09 21:36:52
是的,這是正常化,是的,這是一件好事。如何獲得最終時間戳,原來不夠好?我同意@戈登 - 只是使用規範化的表(禁止_huge_分析需求)。你不需要遊標或'VALUES'子句 - 你可以直接從'SELECT'中插入INSERT,儘管你需要使用四個不同的數據來分隔數據。 – 2012-08-09 22:03:56