sql >> データベース >  >> RDS >> PostgreSQL

カウントに基づいて挿入を制限する一般的なトリガー

    私は同様のタイプのジェネリックトリガーを実行しています。最も難しい部分は、NEWの値エントリを取得することです。 列名に基づいて記録します。

    私はそれを次のようにしています:

    • 変換NEW データを配列に;
    • attnumを見つける 列のインデックスとして使用します。

    このアプローチは、データにカンマがない限り機能します。 :( NEWを変換する他の方法がわかりません またはOLD 変数を値の配列に入れます。

    次の関数が役立つ場合があります:

    CREATE OR REPLACE FUNCTION impose_maximum() RETURNS trigger AS $impose_maximum$
    DECLARE
      _sql  text;
      _cnt  int8;
      _vals text[];
      _anum int4;
      _im   record;
    
    BEGIN
     _vals := string_to_array(translate(trim(NEW::text), '()', ''), ',');
    
     FOR _im IN SELECT * FROM imposed_maximums WHERE table_name = TG_TABLE_NAME LOOP
      SELECT attnum INTO _anum FROM pg_catalog.pg_attribute a
        JOIN pg_catalog.pg_class t ON t.oid = a.attrelid
       WHERE t.relkind = 'r' AND t.relname = TG_TABLE_NAME
         AND NOT a.attisdropped AND a.attname = _im.column_group;
    
      _sql := 'SELECT count('||quote_ident(_im.column_count)||')'||
              ' FROM '||quote_ident(_im.table_name)||
              ' WHERE '||quote_ident(_im.column_group)||' = $1';
    
      EXECUTE _sql INTO _cnt USING _vals[_anum];
    
      IF _cnt > CAST(_im.max_size AS int8) THEN
        RAISE EXCEPTION 'Maximum of % hit for column % in table %(%=%)',
          _im.max_size, _im.column_count,
          _im.table_name, _im.column_group, _vals[_anum];
      END IF;
     END LOOP;
    
     RETURN NEW;
    END; $impose_maximum$ LANGUAGE plpgsql;
    

    この関数は、特定のテーブルに定義されているすべての条件をチェックします。



    1. uuidの配列のPostgreSQLGINインデックス

    2. ネストされたパイプライン関数

    3. DatagridviewにMySQLデータを入力します

    4. 小文字でのMySQL自動変換