2017-02-20 6 views
1

Upsertは、PG(私たちは最近、データベースを使用するように更新しました)のすばらしい新作で、今ではPHPでupsertアダプターを書こうとしています。 。ここでポストグルでphpを使ってプログラムを使ってUpsertする方法

は、私たちがアップサートしたい場合は、我々は何をすべきかです:

INSERT INTO {$this->_name} AS t ({$insertCols}) VALUES ({$insertVals}) 
       ON CONFLICT {$onConflict} DO UPDATE 
       SET {$updateVals} 
       WHERE {$updateWhere} 

私たちは、コード内で、より便利である、機能をsimplierするためにそれを短縮することができます。

ModelTable()->getInstance()->getAdapter->upsert($data, $onConflict, $where); 
//e.g. 
ModelTable()->getInstance()->getAdapter->upsert(['name=>'Denis', 'age'=>36], '(name)', "name = 'Denis'"); 

この場合の使用にされますもっと便利ですが、問題は、$ onConflict変数に入れるために、制限カラム名(名前)または制限名自体を知る必要があることです。上記の例では変数'(name)'です。

テーブルに別の制限を追加したり、古いテーブルの名前を変更したりすると、そのテーブルで動作するPHPコード全体が更新され、新しい制限が追加されます。 name = Denisを持つ行は、それが作成する必要があり、存在しない場合には、更新される、存在する場合はそのので

ModelTable()->getInstance()->getAdapter->upsert(['name=>'Denis', 'age'=>36], "name = 'Denis'"); 

理想のアダプタは、通常のアップデートアダプタのようになります。

ですから、問題は - そのように動作するphpでadaperを作成する方法ですか?行を更新する列名を知っているので、ON CONFLICT ... DO UPDATE文を作成することが可能です。私はそれが我々が今使っている

try { 
...insert 
} catch (Exception $e) { 
...update 
} 

になるのと同じ、矛盾に更新を作りたいです。

ありがとうございます。

答えて

0

をキャッチするようなやり方は、「理由が何であれ挿入物がうまくいかない場合、私はそれを更新しようとします。」これはドメインのコントロールが本当に不足していることを認めます。主キーと競合して更新される行が、同じ表の一意のフィールドと衝突すると拒否されることがあります。

矛盾の理由はモデルに属します。これらは、制約として明示的に実装されたビジネスルールです。モデルレイヤーのみが挿入を拒否し、代わりに行を更新する理由を知っています。したがって、ドメイン定義に関係なくすべてのテーブルで呼び出すことができる汎用のupsertコマンドにすることはできません。

これは、テーブル構造を知っているのと同じ方法でレコードが既存のデータと競合する理由を知っているModelTableインスタンスです(これはあなたの例で推測します)。

+0

try/catchを使用すると制御が不十分だと言うときは正しくありません。あなたは、 'catch'文で更新を行うと、既にテーブルに存在するいくつかの一意のフィールドで行を更新しようとすると例外がスローされることがあります。 一般的な 'upsert'を使用する限り、' ON CONFLICT'節にupdate列のキーを置くだけです。例えば。私が 'upsert( 'table'、[name =" Denis "]、" id = 123 ")'を実行すると、ON CONFLICT文は 'ON CONFLICT(ID)DO UPDATE'になります try/catchアプローチと同等ですが、機能します。 –

+1

私はtry/catchを使用して制御が不足しているとは言わなかったが、私はすべての例外(クラス\例外)を区別せずにキャッチすると制御不足であると言った。例外は、SQLレイヤーの例外または上記のレイヤーからのConnectionExceptionです。何をすべきかを知るためには、例外の種類を知る必要があります。 – greg

+0

ああ、今、私はそれを得た。 –

関連する問題