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

plpgsql-宣言ステートメントで動的テーブル名を使用

    これら5つの異なる種類のデータ/シンボルの主な性質を理解することが重要です。 :

    1。 'my_tbl'

    不明の文字列リテラル タイプ 。 SQLで使用される場合(plpgsqlコードに埋め込まれているかどうかに関係なく)、コンテキストから派生した型に強制変換されます。 。タイプを判別できない場合は、明示的なキャストが必要になる場合があります。例:'my_tbl' ::text

    2。 'my_tbl' ::text

    タイプtextにキャストされた同じ文字列リテラル 。テーブルの名前を保持できますが、実際には単なるテキストです。

    3。 'my_tbl' ::regclass

    オブジェクト識別子(OID) 登録済みのクラスの場合 。表示され、有効なオブジェクト名を表す文字列として入力できます('my_tbl' )。出力は自動的にスキーマ修飾されます('my_schema.my_tbl' )および/または二重引用符('"mY_TbL"' )あいまいまたは違法である場合。通常のテーブルにすることができます 、シーケンス表示マテリアライズドビュー複合タイプ など。この関連する回答の詳細:

    4。 my_tbl_var my_tbl my_tbl_var my_tbl%ROWTYPEの略 )

    DECLAREよく知られている行タイプ (別名複合タイプ)。タイプはシステムテーブルpg_classに登録する必要があります ( regclassと同じ 変数)。これは、参照されるオブジェクトのOIDではなく、実際の行タイプです。 my_tbl_var およびmy_tbl どちらも識別子です ここで、パラメータ化することはできません。任意の行またはレコードを直接キャストすることもできます:(123、'foo')::my_tbl

    5。 my_tbl_varレコード

    DECLARE匿名の記録 。基本的に、まだ不明な行タイプ/まだ定義されていない構造のプレースホルダー。 ほとんどで使用できます 行タイプを使用できる場所の。ただし、レコード変数が割り当てられる前に、そこからフィールドにアクセスすることはできません。

    あなたは1。を混乱させていました 、3。 および4。 5を使用して解決しました。 代わりに。
    しかし、もっとうまくいかない ここ:

    • テーブル全体を選択していますが、行(レコード)変数は一度に1つの行しか保持できません。したがって、最初のものだけが割り当てられて返されます。 ORDER BYはありませんが 条項では、結果は任意であり、いつでも変更できます。 邪悪な罠。

    • recordを使用しているので タイプの場合、フィールドでテストを実行する前に、割り当てられていることを確認する必要があります。そうしないと、空のテーブルの例外が発生します。この場合、 record_var IS NULLを確認してください。 ほぼ同じ仕事をします。ただし、すべてのフィールドにNULLが含まれる行には、コーナーケースがあります。 record_var IS NULL trueと評価されます。テストではさらに注意が必要ですISNOT NULL 。詳細はこちら:

      SQLフィドル にデモを追加しました 以下。

    • この関数は単一のスカラー( boolean )を返します ) 価値。使用:

      RETURN false;
      

      代わりに:

      RETURN QUERY SELECT false;

    機能

    CREATE FUNCTION check_valid(_tbl regclass)
      RETURNS bool AS
    $func$
    DECLARE
       r record;
       _row_ct int;
    BEGIN
       EXECUTE '
       SELECT is_valid, hit_count, hit_limit
       FROM  ' || _tbl || '
       ORDER  <whatever>
       LIMIT  1'            -- replace <whatever> with your sort criteria
       INTO r;              -- only needed columns
    
       GET DIAGNOSTICS _row_ct = ROW_COUNT;
    
       IF _row_ct = 0 THEN  -- necessary, because r may not be assigned
          RETURN false;
       ELSIF NOT r.is_valid OR r.hit_count > r.hit_limit THEN
          RETURN false;
       END IF;
    
       RETURN true;
    END
    $func$  LANGUAGE plpgsql;
    

    SQLフィドル (関数の2つのバリアントと行のデモはNULLです)。

    主なポイント

    • GET DIAGNOSTICS> EXECUTEを使用した動的ステートメントで行が見つかったかどうかを確認します 。

    • IF 式を簡略化できます。

    • パラメータのタイプはregclassです。 、テーブル名だけではありません。このパラメータには誤解を招くような名前「tablename」は使用しません。それはあなたの最初の混乱を増すだけです。それを_tblと呼びます 代わりに。

    返品もしたい場合 可変行タイプのセット:



    1. 名前にドット(。)を含むMySQL列を更新する

    2. SOLR-デルタインポートは機能しませんが、フルインポートは正常に機能します

    3. OBJECTPROPERTY()を使用して、SQLServerでテーブルにDEFAULT制約があるかどうかを確認します。

    4. mysqlのデータ行から改行文字を削除するにはどうすればよいですか?