2013-10-10 24 views
0

我試圖做一個觸發器函數來創建一個基於存儲在變量中的基準日期加上間隔秒數的時間戳。在觸發函數內部訪問變量

此基準日期通過-v選項指定給psql腳本,例如, 「-v start_time ='2013-10-10 13:48:00'」。

我想從一個觸發器函數中訪問這個變量做這樣的事情:

NEW.mytimestamp = timestamp :start_time + interval NEW.elapsed_seconds ' s'; 

不幸的是我無法弄清楚對於正確的語法。有任何想法嗎?

+0

可能重複[你如何在PostgreSQL中使用腳本變量?](http://stackoverflow.com/questions/36959/how-do-you-use-script-variables-in-postgresql) –

+0

不,我在問之前已經讀過。 – Trixl

+0

我會建議編輯問題以突出它與衆不同之處。順便說一下,在另一張紙上,你不應該使用像現在()。如果您正在監控您的腳本花了多長時間,那麼會有一個時間函數產生當前時間,您可以從事務開始時間減去該時間。如果不是這樣,重新定義觸發器就像你想要做的似乎非常可怕。 –

回答

3

這是不可能的。 psql變量(通過:varname訪問)是客戶端變量。觸發器功能在服務器上執行,不能訪問這些變量。

有一種解決方法,但有點困難(不能簡單地通過命令行初始化值)。您可以使用自定義的配置設置變量:

postgres=# select set_config('public.xxx', '10', false); 
set_config 
------------ 
10 
(1 row) 

create or replace function foo_trg() 
returns trigger as $$ 
begin 
    raise notice '%', current_setting('public.xxx'); 
    return new; 
end; 
$$ language plpgsql; 

create table foo(a int); 

create trigger hh before insert on foo for each row execute procedure foo_trg(); 

postgres=# insert into foo values(200); 
NOTICE: 10 
INSERT 0 1 

另一個(更成熟的)技術是使用一個輔助表。

關於第二個想法,觸發參數化(基於某個全局值)通常是一個可怕的想法。它表明你做錯了一些。改用一個函數。

+0

謝謝。我應該意識到這些變量是客戶端! – Trixl

+0

@Trixl:在這些相關答案中設置「全局變量」的更多選項[此處](http://stackoverflow.com/questions/13316773/is-there-a-way-to-define-a-named-constant- in-a-postgresql-query)和[here](http://stackoverflow.com/questions/13172524/passing-user-id-to-postgresql-triggers/13172964)。 –