2012-01-10 5 views
1

PostgreSQL 9.1.0。 OS Ubuntu 11.10。コンパイラはgcc 4.6.1ここCトリガーに挿入されている行からデータを取得するにはどうすればよいですか?

は私のテーブルです:

CREATE TABLE ttest 
(
    x integer, 
    str text 
) 
WITH (
OIDS=FALSE 
); 
ALTER TABLE ttest OWNER TO postgres; 

CREATE TRIGGER tb 
BEFORE INSERT 
ON ttest 
FOR EACH ROW 
EXECUTE PROCEDURE out_trig(); 

out_trigは、C functcionです。

今、私は挿入されている各行からデータを取得しようとしています。ここでは、コードは次のようになります。

if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) 
{ 
    rettuple = trigdata->tg_trigtuple; 
    bool isnull = false; 
    uint32 x=rettuple->t_len; 
    int64 f; 
     f = (int64) GetAttributeByNum(rettuple->t_data, 1, &isnull);//error here 
    elog(INFO,"len of tuple: %d",x); 
    elog(INFO,"first column being inserted x: %d",f); 
} 

IましERROR:レコードの種類が登録されていない

SQL状態:42809

私が間違っているとどのようにそれを正しく行うにしていますか?

+0

このトリガーにCを使用する必要がある理由は何ですか?エラーが発生している行を知っていますか? – Kuberchaun

+0

理由は、同じ行に新しい行が挿入されたときにtcp \ ipを使ってメッセージを送信したいからです。また、コメント行にエラーがスローされます。 – Alexander

答えて

1

GetAttributeByNum(またはGetAttributeByName)は、ディスク上のタプルではなくDatumのみで動作しますが、代わりにheap_getattrを使用します。

あなたはxを整数として宣言しましたが、int64として読み込もうとしました(PostgreSQLは明示的にint8として指定しない限り、整数型にint4を使用します)。

最後に、Datumを返す関数を呼び出すときにDatumGet [YourType]マクロを使用して、値を直接目的のタイプに変換します。

if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) 
{ 
    HeapTuple rettuple = trigdata->tg_trigtuple; 
    TupleDesc tupdesc = trigdata->tg_relation->rd_att; 
    bool isnull = false; 
    uint32 x=rettuple->t_len; 
    int32 att = DatumGetInt32(heap_getattr(rettuple, 1, tupdesc, &isnull)); 
    elog(INFO,"len of tuple: %d",x); 
    if (!isnull) 
     elog(INFO,"first column being inserted x: %d",att); 
    else 
     elog(INFO,"first column being inserted x: NULL"); 
} 

あなたはまた、ユーザ定義のC関数からデータベースへのアクセスを簡素化するSPIインターフェース、を見てみたいことがあります: http://www.postgresql.org/docs/current/interactive/spi.html

ロングとショート、コードは次のようになりべきです

+0

ありがとうございます。すでにSPIでやっていますが、あなたのバージョンも使えます。 – Alexander