Postgres 9.5.4更新触发器功能窗口(滞后和超前)

时间:2017-07-05 08:15:01

标签: ruby-on-rails postgresql

一直在挣扎,希望得到一些帮助 在轨道上运行了很多数学函数并找到了虚假的结果后,我决定爬下来在数据库中执行它,发现它对我来说都是非常可行的,但是当我到达第二个函数时以下错误:

  

PG :: UndefinedFunction:错误:函数updown(整数)不存在   第3行:SELECT" updown" (滞后(updown)结束(按id排序))table_nam ...   ^提示:没有函数匹配给定的名称和参数类型。

迁移:

class CreateSmoothings < ActiveRecord::Migration
def change
create_table :smoothings do |t|
  t.decimal :firstsmprice,    :precision => 8,    :scale => 6
  t.decimal :finalsmprice,    :precision => 8,    :scale => 6
  t.decimal :firstsmdelta,    :precision => 8,    :scale => 6
  t.decimal :finalsmdelta,    :precision => 8,    :scale => 6
  t.integer :updown,          :null => false,     :default => 0
  t.integer :posture
  t.integer :step
  t.references :usdzar,       index: true,        foreign_key: true
  t.references :smoothval,    index: true,        foreign_key: true

  t.timestamps null: false
end
add_index :smoothings, :finalsmprice
end
end

我有一个更新控制器,用于设置来自另一个表的平滑数据,这是触发器触发的时间。第一个触发器就像一个魅力。这是控制器动作,然后是触发器和功能。

#POST / smoothings工作并将所有数据插入到平滑表

def create

# Do the 1st and 2nd SMOOTHINGS
# Get the row with the smoothval_id parameter to use these
sv = Smoothval.find(smoothing_params[:smoothval_id])
fval = sv.fval
sval = sv.sval
svid = sv.id

toremove = Smoothing.where(:smoothval_id => sv.id)
toremove.destroy_all

# For every entry in the table do:
collection = Usdzar.all
collection.each_with_index do |usdzar, i|

    # Declare the previous variables required for id = 1 as
    # the calculation cannot be done as it has no previous id
    # I am sure this can be refactored
    if usdzar.id == 1
      prevprice = usdzar.price
      prevfirstsmprice = usdzar.price
      prevfinalsmprice = usdzar.price
    else
      prevprice = collection[i-1].price
      prevfirstsmprice = Smoothing.last.firstsmprice
      prevfinalsmprice = Smoothing.last.finalsmprice
    end

    # Do the smoothing calcs for the first smoothing using fval (first value)
    firstsmprice = (((fval * usdzar.delta)/100) + prevprice)

    # Find the difference of the current and previous of the first smoothing
    firstsmdelta = firstsmprice - prevfirstsmprice

    # Do the final smooting with the fval
    finalsmprice = ((sval * firstsmdelta)/100) + prevfirstsmprice

    # Find the differance of the current and previous of the second smoothing
    finalsmdelta = finalsmprice - prevfinalsmprice

    # Create the rows at end of iteration
    Smoothing.create!(
      usdzar_id: usdzar.id,
      smoothval_id: sv.id,
      firstsmprice: firstsmprice,
      firstsmdelta: firstsmdelta,
      finalsmprice: finalsmprice,
      finalsmdelta: finalsmdelta
    )
end
redirect_to smoothings_url, notice: 'Old smoothings removed and new smoothings successfully created.'

触发功能和触发器有效: - )

CREATE TRIGGER a_smoothings_trigger
AFTER INSERT
ON smoothings
FOR EACH ROW
EXECUTE PROCEDURE make_updowns_trg();

CREATE FUNCTION make_updowns_trg() 
RETURNS trigger
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
update smoothings
set updown =  case when  (finalsmdelta < 0) then 1
                when  (finalsmdelta > 0 ) then 0
          else 2 end;
RETURN NULL; 
END
$BODY$;

这(上述)运行良好。 我接下来要做的是通过另一个触发器和函数扩展函数(现在知道它们按字母顺序运行 触发器/功能用于采取&#34; updown&#34; (0,1或2:向上,向下或相同是轨道中的枚举)和:

如果updown和next updown相同,则更新为2(中间) 如果updown大于next&#34; updown&#34;更新为1(高) 如果updown小于下一个&#34; updown&#34;更新为0(低)

CREATE FUNCTION public.make_high_lows_trg()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE NOT LEAKPROOF 
AS $BODY$
BEGIN
WITH next_updown AS
(SELECT updown (lag(updown) over (order by id)) table_name FROM smoothings 
ORDER BY id DESC) 
update smoothings
set posture =  case when updown < next_updown then 1
                when updown > next_updown then 0
          else 2 end;
RETURN NULL; 
END
$BODY$;

CREATE TRIGGER b_smoothings_trigger
AFTER INSERT
ON public.smoothings
FOR EACH ROW
EXECUTE PROCEDURE public.make_high_lows_trg();

控制器的模型:

class Smoothing < ActiveRecord::Base

enum updown: [:up, :down, :same]
enum posture: [:high, :low, :inbetween]

belongs_to :usdzar
belongs_to :smoothval

end

我把这一切都在控制器中运行,因为我的模型方法编码非常糟糕并且一切都在运行,但是在测试后发现数据非常不可靠。在此先感谢您的帮助。我对Postgres中的函数数量感到震惊,当我遇到窗口函数时认为它是合适的但可以克服障碍。我知道(来自psql文档)你不能把滞后/主导窗口放到函数的更新部分,但是显然有关于如何正确执行sql块的问题

此查询在运行第一个查询后运行,但如何更新表格:

with myUpdowns as (
 Select id, updown, Lag(updown) over (order by id desc) next_updown from smoothings
)
select *
from myUpdowns
where updown < next_updown;

现在我得到了一个正确更新的高点:我现在正试图做到高点的全面传播。低和中间(0,1和2)。如果您有任何建议,我很乐意听到。向表中添加高位的更新触发器如下所示:

CREATE FUNCTION make_high_lows_trg()
RETURNS trigger
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN

UPDATE smoothings

SET posture = 0
FROM (
Select id, updown, Lag(updown) over (order by id desc) next_updown from smoothings
) as highs
WHERE highs.updown < highs.next_updown 
AND smoothings.id = highs.id;

RETURN NULL; 
END
$BODY$;

触发器:

CREATE TRIGGER b_smoothings_trigger
AFTER INSERT
ON smoothings
FOR EACH ROW
EXECUTE PROCEDURE make_high_lows_trg();
嗯,现在如何做低和中间,实际上只是高低都很好

0 个答案:

没有答案