2

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

助けてくれてありがとう、ペトル

4

2 に答える 2

3

4 つの列を持つテーブルを、各行がソース テーブルの行番号とソース テーブルの列を表す 1 つのテーブルに変換するだけでよい場合は、次の例を参照してください。

ここにSQLFiddleがあります

create table fourColumns
(
    column1 varchar(50),
    column2 varchar(50),
    column3 varchar(50),
    column4 varchar(50)
)

insert into fourColumns select 'A','B','C','D'
insert into fourColumns select 'E','F','G','H'

    ;with MyCTE (lineNumber, columnNumber, Result)
as
(
    select ROW_NUMBER() OVER(ORDER BY column1 ASC) AS Row, 1, column1  
    from fourColumns
    union all
    select ROW_NUMBER() OVER(ORDER BY column2 ASC) AS Row, 2, column2  
    from fourColumns
    union all
    select ROW_NUMBER() OVER(ORDER BY column3 ASC) AS Row, 3, column3  
    from fourColumns
    union all
    select ROW_NUMBER() OVER(ORDER BY column4 ASC) AS Row, 4, column4  
    from fourColumns        
)
    -- add insert here
select lineNumber, 
       columnNumber,
       Result
 from MyCTE
 order by lineNumber
于 2012-08-09T21:59:16.427 に答える
1
INSERT INTO dbo.line_sensor_value
(UTC, line_no, sensor_no, sensor_value)
select UTC, line_no, sensor_no, temperature_1 as sensor_value from dbo.Data
union
select UTC, line_no, sensor_no, temperature_2 as sensor_value from dbo.Data
union
select UTC, line_no, sensor_no, temperature_3 as sensor_value from dbo.Data
union
select UTC, line_no, sensor_no, temperature_4 as sensor_value from dbo.Data
于 2012-08-09T22:54:24.673 に答える