[pgsql-jp: 28232] Re: トリガファンクションのカラム名を変数で使いたい

Chie.M gontakun @ check.ne.jp
2002年 12月 9日 (月) 19:51:50 JST


Chieです。Mashikiさん、ありがとうございます。

> >一つのトリガを、汎用的に使いまわしたいと考えています。
> >私がやろうとしているのは、テーブル更新時の履歴をとる事です。
>  :
> >それで、私は更新履歴を持つテーブルは下記のように
> >したいと思っています。
> > 更新日、テーブル名、カラム名、旧データ、新データ
> >
> >このテーブルに更新履歴のとりたい全テーブルの
> >更新したデータだけが格納されるようにしたいのです。
> 
> 1つのテーブルに変更履歴を格納するのは面白いけど、
> 列「旧データ」と列「新データ」の型はどうするのでしょうか。

更新履歴のログは参照でしか使わないのです。
私が作りたいのは、契約内容などを格納するデータの更新履歴です。

契約のレコードは契約1本につき1レコード持たせますが、
入力時に契約の内容を間違えた後に修正した時や、
契約内容の変更が発生した場合に、何処の項目がどういう風に
変更になったかを「参照」させるだけなのです。

よって全ての履歴データをTEXTにキャストして保存します。

過去の契約の売上と原価データを計算させる事はあっても、
更新の履歴テーブル上の売上と原価データを計算させる事はありえないのです。

GUI としては契約内容参照フォームなどで、変更のあった項目に
カーソルを持っていくと、更新履歴の内容がヒントテキストで表示させる
と言う風にする予定です。

よってこの方法ですと、更新履歴(ログ)に格納されたデータを使って
何らかの別の操作がしたいような場合はちょっと難しいです。
あるいは、システムカタログからカラム名だけでなく型も取得できるので、
その型を使ってキャストする関数でも作っておけば使えますが。

参照しかしないのであれば、ログの為だけに2倍テーブルを作るのは
無駄だなーと考えました。

> >そこで、テーブル名とカラム名を取得して、更新したデータだけを
> >格納するトリガを作成し、そのトリガを、更新履歴を取りたいテーブル
> >全てに適用したいと考えているのです。
>  :
> >または、このような場合はどのような関数を作るのが適切なのか
> 
> 別の方法ですが、テーブル名を引数として渡すと、「渡されたテーブルの
> 情報をシステムカタログから取得して、更新履歴を取るトリガーファンク
> ションとトリガーをCreateする」ようなファンクションを定義して、

なるほど!「トリガーファンクションとトリガーをCreateする」ファンクション
というのが作れる事を知りませんでした。
確かにマニュアルに出てますね!面白そうですね、試してみます!

ADOの方でカラム名を取得してファンクションをCREATE OR REPLACE 
するようなものを作ってみたんですが、これだとこのファンクションを動かすのを
VBのイベントの方に頼るしかないので、トリガの意味が
あまりなくなってしまうのです。
しかも、今テストしたらちょっと重い感じがしました。

> ログ取得の必要のあるテーブルをCreate または Alter したときに呼び出せば
> よいのではないでしょうか。
・・・
> もし、テーブルに修正が入ったときも、ALTER TABLE テーブルA...:の後、
> select SetTriger('テーブルA');を流すだけくらいなら、手間にも
> ならないとおもいますが、いかがでしょうか。

なるほど、これだとだいぶすっきりしますし、変数にカラム名を
使っていても問題なさそうですね。

定義したファンクションから、「ログ取得の必要のあるテーブルを
Create または Alter したときに呼び出」すと言うことは、
テーブルが作成されたり変更された時に、
そのテーブルのカラム名が使われた更新履歴用ファンクションを
関数を呼び出すだけで作成できるようにしておく、と言うことですね。

当初は、汎用で使える関数で取り回したいと思っていたので、
この方法でも更新ログをとるトリガの実行時に、NEW.カラム名等を
指定した関数を作成していく事も出来る、と考えたりしていました。

が、更新履歴をとりたいテーブルごとに関数を作らないといけない
事には変わりない上、更新時の度にファンクションを発行させるのが
無駄な事に気づいてやめました(^_^;)

テーブルのCREATEかALTER時に関数を実行させてファンクションを
するという方法でやってみます!

> # ファンクションの中から「create function文」は使ったことが
> # あります(なんとマニュアルにも例で載ってる)が、
> #「create triger文」は未確認ですので注意してください。 

これについても検証している最中です。結果出たらご報告します。
ありがとうございました。
------------------------
From:Chie.M
 gontakun @ check.ne.jp
------------------------




pgsql-jp メーリングリストの案内