Trigger

FUNCTION BEFORE TRIGGER INEXISTENT OPERATOR 日期 > = 雙精度

  • March 8, 2019

在“pubblicazione”表中,我想插入“legge_approvata”表中包含的元組的一些欄位,但要執行此操作,頒布日期必須與法律發布日期在同一年和同一年。如果滿足此條件,則函式更新其他屬性並插入元組的其他欄位,即更新已批准規則的計數器,再添加一個並同意將所有其他屬性值插入 NEW。

我希望我現在更清楚了。

我試圖通過首先在if中進行選擇來隔離錯誤,但是我發現您無法將日期轉換為字元串,那麼您該怎麼做呢?我要把它轉換成一個字元嗎?但隨後將需要另一個週期。

我想將日期類型屬性中的月份和年份提取到 law_approvata.data_promulgazione

SELECT EXTRACT(MONTH FROM TIMESTAMP legge_approvata.data_promulgazione);
SELECT EXTRACT(YEAR FROM TIMESTAMP  legge_approvata.data_promulgazione);
ERRORE:  errore di sintassi a o presso "legge_approvata"
LINE 5:  SELECT EXTRACT(MONTH FROM TIMESTAMP legge_approvata.data_pr...
                                            ^
********** Error **********

ERRORE: errore di sintassi a o presso "legge_approvata"
SQL state: 42601}

詢問:

INSERT INTO public.pubblicazione(
  titolo_legge,
  legislatura,
  gazzetta_numero,
  data_pubblicazione, 
  leggi_legislatura,
  tot_num_leggi,
  testo,
   relatore,
  numero_legge)
VALUES (
   '[Legge di bilancio 2018] Bilancio di previsione dello Stato per l anno finanziario 2018 e bilancio pluriennale per il triennio 2018-2020',
   17,
  '302' ,--gazzetta_numero
  '29/12/2017' , -- data_pubblicazione
   0,--leggi_legislatura int
   0,
  'https://parlamento17.openpolis.it/atto/documento/id/523404' ,
  '{"Marcello Gualdani","Magda Angela Zanoni","Pier Carlo Padoan"}' ,
 'S.2960-B');

觸發前:

CREATE TRIGGER inserimento
 BEFORE INSERT
 ON public.pubblicazione
 FOR EACH ROW
 EXECUTE PROCEDURE public.inserimento_pubblicazione();

觸發功能

  begin
  if exists (select 1 from legge_approvata
             where NEW.titolo_legge = legge_approvata.titolo and 
              new.data_pubblicazione between 
                 (SELECT EXTRACT(MONTH FROM /*TIMESTAMP*/ legge_approvata.data_promulgazione))and
                 (SELECT EXTRACT(YEAR FROM /*TIMESTAMP */ legge_approvata.data_promulgazione)) 
            )
  then
      new.leggi_legislatura= (select count(*) from legge_approvata where NEW.titolo_legge = legge_approvata.titolo and
                        data_promulgazione between
                        (SELECT EXTRACT(MONTH FROM /*TIMESTAMP*/ legge_approvata.data_promulgazione))and
                 (SELECT EXTRACT(YEAR FROM /*TIMESTAMP*/  legge_approvata.data_promulgazione)) and
                 legge_approvata.legislatura=new.legislatura )
                 +1;
      new.tot_num_leggi=(select count(*) from legge_approvata);
      return new;
  else
      raise exception '% non è stata promulgata nello stesso mese e anno %',new.titolo_legge, legge_approvata.data_promulgazione;
  end if;
end;}

輸出錯誤:

ERRORE:  l'operatore non esiste: date >= double precision
LINE 3:                new.data_pubblicazione between 
                                             ^
HINT:  Nessun operatore trovato con nome e tipi di argomenti forniti. Potrebbe essere necessario convertire i tipi esplicitamente.
QUERY:  SELECT exists (select 1 from legge_approvata
             where NEW.titolo_legge = legge_approvata.titolo and 
              new.data_pubblicazione between 
                 (SELECT EXTRACT(MONTH FROM /*TIMESTAMP*/ legge_approvata.data_promulgazione))and
                 (SELECT EXTRACT(YEAR FROM /*TIMESTAMP */ legge_approvata.data_promulgazione)) 
            )
CONTEXT:  funzione PL/pgSQL inserimento_pubblicazione() riga 5 a IF
********** Error **********

ERRORE: l'operatore non esiste: date >= double precision
SQL state: 42883
Hint: Nessun operatore trovato con nome e tipi di argomenti forniti. Potrebbe essere necessario convertire i tipi esplicitamente.
Context: funzione PL/pgSQL inserimento_pubblicazione() riga 5 a IF

謝謝你。

例子:

SELECT EXTRACT(MONTH FROM TIMESTAMP '25/03/1982');
SELECT EXTRACT(YEAR FROM TIMESTAMP '2018-02-16');

在此處輸入圖像描述

開採年

在此處輸入圖像描述

提取月

你把事情複雜化了。

一方面,您不必SELECT在每個函式呼叫之前都寫。select extract(...)可以簡單地替換為extract(...)

但是您似乎對函式的作用感到困惑。

作為data_pubblicazione日期值,這個(簡化的)條件

new.data_pubblicazione between EXTRACT(MONTH FROM data_promulgazione)
                          and EXTRACT(YEAR FROM data_promulgazione)

歸結為:

where '2019-03-08` between 3 and 2019

顯然這沒有任何意義。一個比較的比較雙方需要是同一類型。

您只想檢查兩個日期是否在同一個月。您可以使用 usedate_trunc()to_char()將兩個日期“標準化”為月初:

date_trunc('month', new.data_pubblicazione) = date_trunc('month', data_promulgazione)

或使用to_char()

to_char(new.data_pubblicazione, 'yyyy-mm') = to_char(data_promulgazione, 'yyyy-mm')

理論上你可以使用提取物,但在我看來,這使得條件非常難以理解

where (extract(year from new.data_pubblicazione), 
       extract(month from new.data_pubblicazione)) = (extract(year from data_promulgazione), 
                                                      extract(month from data_promulgazione))

上述條件導致類似:where (2019,3) = (2019,3)

所以if語句應該是這樣的:

if exists (select 1 
         from legge_approvata la
         where NEW.titolo_legge = la.titolo 
           and date_trunc('month', new.data_pubblicazione) = date_trunc('month', la.data_promulgazione)
        )
then 

分配也需要調整。我個人更喜歡select ... into variable from ...在 PL/pgSQL 中使用,但這是風格問題:

  select count(*) + 1
    into new.leggi_legislatura  -- this replaces the :=  assignment
  from legge_approvata la 
  where NEW.titolo_legge = la.titolo 
    and date_trunc('month', new.data_pubblicazione) = date_trunc('month', la.data_promulgazione)
    and la.legislatura = new.legislatura;

引用自:https://dba.stackexchange.com/questions/231528