如何将新列添加到一组Function记录中

时间:2017-03-22 05:17:31

标签: sql postgresql function record

我正在创建一个函数,该函数从标题为" Sequence"的表中返回一组记录。作为此表的一部分,我还在分析另一个表(" Log_Alpha")并将适当的信息插入到记录中。到目前为止,我所做的是覆盖现有的列数据,然后在我的select函数调用中重命名该列(IE SELECT * FROM Production1(参数)为tbl(xxx,xxx,xxx,NewColumnName Real,xxx,xxx) ...)

这非常有效,但我需要保留原始数据,因此更愿意在记录中添加新列。但是我该怎么做呢,因为记录直接从表中获取其列名"序列"。

我的代码显示 rc。" seqLogsIn" 是捕获(平均每日SED)数据的列。然后通过在此代码底部看到的SELECT查询从数据库中调用它,其中该列重命名为" AvLogSED"

这是完整的功能,但您实际上只需要关注 SELECT AVG(" logSED")部分。

为了澄清,我想在记录中创建一个新列(称为AvLogSED,作为函数的一部分)并将数据注入到新列中,而不是"挪用" seqLogsIn。我该怎么做?

我正在运行PostgreSQL 9.2.9,由Windows 7桌面PC上的Visual C ++ build 1600,64位编译(本地服务器副本也在桌面上运行)。

-- Function: production1(timestamp without time zone, timestamp without time zone)    
-- DROP FUNCTION production1(timestamp without time zone, timestamp without time zone);

CREATE OR REPLACE FUNCTION production1(tme1 timestamp without time zone, tme2 timestamp without time zone)
  RETURNS SETOF record AS
$BODY$
DECLARE
  rc Record;
  tmeA timestamp without time zone;
  tmeB timestamp without time zone;
  AverageSED Real;

BEGIN

tmeA := tme1 + '1 day'::interval;
tmeB := tme2 + '1 day'::interval;

-- get average SED for all logs in time/date range
SELECT AVG("logSED")::Real
  FROM "Log_Alpha"
  WHERE "logTime" >= DATE_TRUNC('DAY', tme1) AND "logTime" < DATE_TRUNC('DAY', tme2 + '1 day'::interval) -- Calculate average for each day from 00:00 hours from first day thru to 23:59:59.99 for last day
  INTO averageSED;

  FOR rc IN 
    SELECT *, averageSED 
    FROM "Sequence"
    WHERE "Sequence"."seqMinute" = 150 AND "Sequence"."seqTime" >= tmeA AND "Sequence"."seqTime" <= tmeB
    ORDER BY "Sequence"."seqTime" 

  LOOP
    rc."seqTime" = rc."seqTime" - '1 day'::interval;

    -- Use a subquery to calculate the average SED for all logs for the day pertaining to this record date field
    SELECT AVG("logSED")::Real into rc."seqLogsIn" FROM "Log_Alpha" -- Replace column seqLogsIn data from sequence table with Daily Average SED data. The column title can be renamed in function (SELECT) call as required
      WHERE "Log_Alpha"."logTime" >= DATE_TRUNC('DAY', rc."seqTime") and "Log_Alpha"."logTime" < (DATE_TRUNC('DAY', rc."seqTime") + '1 day'::interval); -- Date truncated (always start at 00:00 hours of the day) to counter offset induced by mn variable

    RETURN NEXT rc;  
  END LOOP;
END
$BODY$
  LANGUAGE plpgsql STABLE
  COST 100
  ROWS 1000;
ALTER FUNCTION production1(timestamp without time zone, timestamp without time zone)
  OWNER TO postgres;

这是选择函数调用&#34;重命名&#34;适当的列到AvLogSED。

select * from production1('2016-02-27 00:00:00','2016-03-11 00:00:00') as tbl(seqTime timestamp without time zone,seqMinute integer,AvLogSED Real,seqLogVolIn Real,seqFinishedVol Real,seqChipTonnes Real,seqSawdustTonnes Real,seqBinSortVol Real,seqTraySortVol Real,seqFlitchSortVol Real,seqBinSortPieces Real,seqTraySortPieces Real,seqFlitchSortPieces Real,seqBinSortRejects Real,seqBinSortSlash Real,seqTraySortRejects Real,seqTraySortSlash Real,seqCanterCants Real,seqSecBandCants Real,seqSecBandRecycled Real,seqCS1Cants Real,seqCS3Cants Real,seqE1Pieces Real,seqE1ManualRejects Real,seqE1OperatorRejects Real,seqE1ThicknessRejects Real,seqE1NoSortRejects Real,seqE1VolumeIn Real,seqE1VolumeOut Real,seqE2Pieces Real,seqE2ManualRejects Real,seqE2OperatorRejects Real,seqE2ThicknessRejects Real,seqE2NoSortRejects Real,seqE2VolumeIn Real,seqE2VolumeOut Real,seqE1Bypass Real,seqE2Bypass Real,seqBSVolumeIn Real,seqPrimaryRuntime Real,seqBinLugSpeed Real,seqBinLugFill Real,seqTrayLugSpeed Real,seqTrayLugFill Real,seqCompressor1kWh Real,seqCompressor2kWh Real,seqCompressor3kWh Real,seqCompressor4kWh Real,seqKiln1and2GJ Real,seqKiln3GJ Real,seqKiln4GJ Real,seqKiln5GJ Real,seqKiln6GJ Real,seqKiln7GJ Real,seqKiln8GJ Real,seqKiln9GJ Real,seqKiln10GJ Real,seqKiln11GJ Real,seqKiln12GJ Real,seqFlitchTray10 Real,seqFlitchReturn Real,seqBSLiftOut Real,seqSecCantRuntime Real,seqSecBandRuntime Real,seqSecCS1Runtime Real,seqSecCS3Runtime Real,seqEdger1Runtime Real,seqEdger2Runtime Real,seqBinSorterRuntime Real,seqTraySorterRuntime Real,seqFlitchSorterRuntime Real,seqReEntryE1Minutes Real,seqReEntryChipMinutes Real,seqAwaitingLogs Real,seqBSUtilisation Real,seqTSUtilisation Real,seqFSUtilisation Real,seqDebarkerRuntime Real,seqReEntryChipCount Real,seqReEntryE1Count Real,Reserved2 Real,Reserved3 Real,Reserved4 Real,Reserved5 Real,Reserved6 Real,AverageSED Real)

2 个答案:

答案 0 :(得分:0)

您可以返回如下任意记录:

RETURN NEXT ROW(val1, val2, ...);

这样您就不受现有类型的限制。

答案 1 :(得分:0)

发现解决方案如下:

FOR rc IN
    SELECT *, AverageSED, avDailySED
    FROM "Sequence"
    WHERE "Sequence"."seqMinute" = mn AND "Sequence"."seqTime" >= tmeA AND "Sequence"."seqTime" <= tmeB
    ORDER BY "Sequence"."seqTime"
  LOOP

通过将AverageSED和avDailySED添加到SELECT,这些列会自动添加到rc记录中。我发现的一个钩子是我必须在记录rc中明确地将数据推送到avDailySED。我的意思是我现有的代码行:

SELECT AVG("logSED")::Real into avDailySED FROM "Log_Alpha" -- Store average SED value in new column

会导致空白的avDailySED列。改为此解决了这个问题:

SELECT AVG("logSED")::Real into rc.avDailySED FROM "Log_Alpha" -- Store average SED value in new column