Postgres在所有表格上创建通用功能

时间:2017-06-26 11:29:59

标签: postgresql function plpgsql

我有一些数据库表。 我想在复制行上写入universtal postgres函数到历史表 我有桌子:

CREATE OR REPLACE FUNCTION copy_history_f() RETURNS TRIGGER AS
$BODY$
  DECLARE
    tablename_h text:= TG_TABLE_NAME || '_h';
  BEGIN
     EXECUTE 'INSERT INTO  ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(tablename_h) || ' VALUES (' || OLD.* ||')';
    RETURN NULL;
  END; 
$BODY$
LANGUAGE plpgsql VOLATILE;

我编写了函数(使用help stackoverflow)

ERROR:  syntax error at or near ","
ROW 1: ...RT INTO  table1_h VALUES ((12,,,0,,"Anto...

功能已创建,但更新后错误。

if($form_id == 21){

$url = 'https://secure4.mline.co.uk/DavidFarrell/php/NewMortgage.php';
$fields = array(
    //Mandatory fields go here:
    'MortgageMode' => urlencode(1), // OR 'CommercialMode => urlendcode(1), for CommercialKeeper
    'StagePK' => urlencode(25),
    'AdvisorPK' => urlencode(1),
    'Surname1'=>urlencode($_POST['[861]']),

    //Other fields to post into go here:

//Mortgage Details
//'LenderPK'=>urlencode(1),
//'InterestRateTypePK'=>urlencode(2),
//'Rate'=>urlencode(3.45),
//'DealTerm'=>urlencode(5),
//'Term'=>urlencode(25),
//'ActionPK'=>urlencode(11),
//'ActionText'=>urlencode($_POST['Notes']),

//Applicant Details
//'Forename1'=>urlencode($_POST['859']),
//'Email1'=>urlencode($_POST['Emailaddress'][864]),
//'DayPhone'=>urlencode($_POST['[867]']),
//'MobilePhone'=>urlencode($_POST['MobilePhone1'][866]),
//'Forename2'=>urlencode($_POST['[880]']),
//'Surname2'=>urlencode($_POST['[882]']),
//'MidNameApp1'=>urlencode($_POST['[860]']),
//'MidNameApp2'=>urlencode($_POST['[881]']),

    //Submit is also mandatory and typically is placed at the end of your array
'submit'=>true
);

// Loops through the $fields array and results in a string variable called $fields_string which is a URL friendly string
foreach($fields as $key => $value)
{
    //adds the key which is the eKeeper field followed by an '=', followed by and ampersand (&)
    $fields_string.=$key.'='.$value.'&';       
}
//trims any whitespace and cleans up the $fields_string variable
rtrim($fields_string,'&');

// Initialises a cURL connection
$ch = curl_init();


//Sets the URL to post into using the $url variable that was initialised earlier
curl_setopt($curl_connection, CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_URL,$url);
// Sets the number of fields to be passed, this is achieved by using the count() function to count the elements in the $fields array.
//curl_setopt($ch,CURLOPT_POST,count($fields));
// Sets the string that contains the eKeeper fields and their values ($fields_string)
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
//curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
// Sets the return transfer option to true so that the return value after execution
  // curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
  curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, false);

// Executes the curl session. must not be done until after the session has been initilised and the relevant curl options have been set.
$result = curl_exec($ch);

// Closes the connection/curl session
curl_close($ch);
} 

我知道这个插页中的错误在哪里,但我不知道如何修复它。 结构表table1和table1_h是相同的,但table1_h还有一列(id_h)

你能帮助我,我是如何创建psql函数的?

揍你。

2 个答案:

答案 0 :(得分:4)

drop table if exists t;
drop table if exists t_h;
drop function if exists ftg();

create table t(i serial, x numeric);
insert into t(x) values(1.1),(2.2);

create table t_h(i int, x numeric);

create function ftg() returns trigger language plpgsql as $ftg$
declare
  tablename_h text:= TG_TABLE_NAME || '_h';
begin
  execute format($q$ insert into %I.%I select $1.*; $q$, TG_TABLE_SCHEMA, tablename_h) using old;
  return null;
end $ftg$;

create trigger tg_t after delete on t for each row execute procedure ftg();

delete from t where i = 1;
select * from t_h;

dbfiddle

更新它解决了您的问题,但我认为您希望在历史记录表中获得更多信息。它会更复杂一点:

drop table if exists t;
drop table if exists t_h;
drop function if exists ftg();

create table t(i serial, x numeric);
insert into t(x) values(1.1),(2.2);

create table t_h(
  hi serial,      -- just ID
  hd timestamp,   -- timestamp
  hu text,        -- user who made changes
  ha text,        -- action
  i int, x numeric
);

create function ftg() returns trigger language plpgsql as $ftg$
declare
  tablename_h text:= TG_TABLE_NAME || '_h';
begin
  execute format(
    $q$
      insert into %I.%I
        select
          nextval(%L || '_hi_seq'),
          clock_timestamp(),
          current_user,
          %L,
          $1.*
    $q$, TG_TABLE_SCHEMA, tablename_h, tablename_h, TG_OP) using old;
  return null;
end $ftg$;

create trigger tg_t after delete or update on t for each row execute procedure ftg();

update t set x = x * 2;
update t set x = x * 2 where i = 2;
delete from t where i = 1;

select * from t_h;

dbfiddle

答案 1 :(得分:1)

我假设您正在插入旧版' table1到table1_h的值。

附加列是您的问题。使用不指定列的插入时,必须使用匹配的数字和插入类型。

您必须使用列引用。

例如。

Insert into table1_h(column1, column2, column3) 
values (a,b,c)

考虑表table1_h中附加列的默认值。