1 つの宛先テーブルに変換する必要があるソース テーブルが 1 つあります。ソース テーブルには、センサー値を含む 4 つの列が含まれています。宛先テーブルには、単一のセンサー値を含む 4 つの行と、センサーの番号を表す 1 つの列 (ソース テーブルの各行) が含まれている必要があります。つまり、宛先テーブルには 4 倍の行が含まれます。(私はこれを正規化と呼んでいると思います。少なくとも、将来、多かれ少なかれ、または異なるセンサーが使用されるようになると、より実用的になると思います。)
説明する背景情報。私はすでに、単一行に対してそれを行う挿入トリガーを正常に試しました。
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
助けてくれてありがとう、ペトル