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

Spring JpaRepositoryで疑問符(?)文字をエスケープする方法

    ?をエスケープする場合 不可能な場合は、別の名前で重複する演算子を作成できます。

    新しい演算子

    Postgresで演算子を作成するための構文:

    CREATE OPERATOR name (
        PROCEDURE = function_name
        [, LEFTARG = left_type ] [, RIGHTARG = right_type ]
        [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
        [, RESTRICT = res_proc ] [, JOIN = join_proc ]
        [, HASHES ] [, MERGES ]
    )
    

    ?|の場合 jsonbで使用されます

    CREATE OPERATOR ^|(
      PROCEDURE = jsonb_exists_any,
      LEFTARG = jsonb,
      RIGHTARG = _text,
      RESTRICT = contsel,
      JOIN = contjoinsel);
    

    ^|を使用しました 例として、別名。このリストの任意のシーケンスにすることができます:+ - * / < > = ~ ! @ # % ^ & | ?`。

    pg_catalog.pg_operatorテーブルをクエリすると、関心のある演算子の現在の定義を見つけることができます。

    SELECT oid, *
      FROM pg_catalog.pg_operator
     WHERE oprname = '?|'
       AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
    

    pgAdminなどのGUIツールを使用して、pg_catalogを参照することもできます。 SQL定義を再利用できるようにするため。

    インデックスの有効化

    この「新しい」演算子にインデックスを使用する場合は、新しい演算子クラスとオプションでファミリを作成する必要があります。この場合、デフォルトのオペレーターがすでに戦略スロットを使用しているため、既存のファミリーに追加できないため、両方が必要です。

    オペレーターの場合と同様に、pgAdminなどのGUIツールを使用してオペレータークラスを参照し、コピーして貼り付けることをお勧めします。

    まず、複製した演算子のOIDを取得します:

    SELECT oid, *
      FROM pg_catalog.pg_operator
     WHERE oprname = '?|'
       AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
    

    オペレーターファミリーについても同じです(代わりにオペレータークラステーブルから取得します)。これは?|をサポートするものであるため、ginクラスを探しています。 。 opcdefault オプションのクラスjsonb_path_opsがあるため、が使用されます この演算子をサポートしていません:

    SELECT opcfamily
      FROM pg_opclass
     WHERE opcintype = (SELECT oid FROM pg_type WHERE typname = 'jsonb')
       AND opcmethod = (SELECT oid FROM pg_am WHERE amname = 'gin')
       AND opcdefault
    

    次に、複製したオペレーターが使用する戦略を取得します:

    SELECT amopstrategy,
           (SELECT typname FROM pg_type WHERE oid = amoplefttype) AS left_t, 
           (SELECT typname FROM pg_type WHERE oid = amoprighttype) AS right_t,*
    FROM pg_amop
    WHERE amopfamily = 4036 --family oid
      AND amopopr = 3248 --operator oid
    

    次に、クラスで使用される関数:

    SELECT amprocnum, amproc::text, pg_get_function_identity_arguments(amproc::oid) AS args,
          (SELECT typname FROM pg_type WHERE oid = amproclefttype) AS left_t,
          (SELECT typname FROM pg_type WHERE oid = amprocrighttype) AS right_t,*
    FROM pg_amproc
    WHERE amprocfamily = 4036 --op family
    

    これにより、この演算子クラスが表示されます。オペレーターファミリーがまだ存在しない場合は作成されます。

    CREATE OPERATOR CLASS jsonb_ops_custom
       FOR TYPE jsonb USING gin AS
       OPERATOR 10  ^|(jsonb, _text),
       FUNCTION 1  gin_compare_jsonb(text, text),
       FUNCTION 2  gin_extract_jsonb(jsonb, internal, internal),
       FUNCTION 3  gin_extract_jsonb_query(jsonb, internal, smallint, internal, internal, internal, internal),
       FUNCTION 4  gin_consistent_jsonb(internal, smallint, jsonb, integer, internal, internal, internal, internal),
       FUNCTION 6  gin_triconsistent_jsonb(internal, smallint, jsonb, integer, internal, internal, internal);
    

    ここで、作成された演算子名を使用してインデックスを作成する必要があります。たとえば、次のようになります。

    CREATE INDEX ON jsonb_table USING gin(jsonb_column jsonb_ops_custom)
    

    そして、インデックスを使用できるはずです:

    SET enable_seqscan = off;
    EXPLAIN ANALYZE
    SELECT * FROM jsonb_table WHERE jsonb_column ^| array['b', 'c'];
    


    1. WindowsPowerShellのSalesforceSOQL

    2. PostgreSQLの日付に月を追加

    3. MySQLのローリングアップグレードを実行する方法

    4. MySQLクエリをスケジュールする方法は?