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

quote_ident()は、最初に列名に引用符を追加しません

    ASを省略しないでください 列エイリアスのキーワード

    ではない正確に。キーワードASを省略したため、爆発します 省略してはならない場所。

    これは機能します:

    SELECT 'select ' 
    || string_agg(
            case when udt_name in ('varchar', 'text')
                then 'left(' || quote_ident(column_name) || ', 65535) AS '  -- !!
                  ||  quote_ident(column_name)
            else quote_ident(column_name)
            end, ', ' order by ordinal_position) 
    || ' from "public"."MyTableName"'
    FROM information_schema.columns c
    join parse_ident('"public"."MyTableName"') t 
    on t[1] = table_schema and t[2] = table_name;
    

    生産:

    SELECT id, left(first, 65535) AS first from "public"."MyTableName";
    

    これは順番に期待どおりに機能します。

    についてのマニュアルASキーワード」

    キーワードASを省略してもかまいません テーブルエイリアス用ですが、列エイリアス用ではありません。

    first 予約語 ではありません Postgresで。 (以前は、古いSQL標準SQL-92で「予約」されていましたが、標準SQLでも「予約」されていません。)「非予約」 *正確には。 マニュアル

    ASを省略 まさにそのようなコンテキストになります。

    quote_ident() 確実に動作します。 マニュアル:

    format() 指定子%Iを使用 同じことをします。

    予約語は言及されていませんが、関係なく適切に引用されています。正確には、「予約済み」とマークされたすべてのキーワード または"(関数またはタイプにすることはできません)" の「PostgreSQL」列にあります。 SQLキーワード テーブル

    それを追加するためにドキュメントのバグを報告します。

    確実に: quote_all_identifiers

    絶対に確信を持ち、追加されたすべてのノイズを気にしない場合は、Postgresにすべてを引用させることができます。 構成パラメーターquote_all_identifiersを持つ識別子 。 マニュアル:

    これには、quote_ident()からの出力が含まれます およびformat()しません 追加されたすべてのノイズを恐れて、それを行います。

    SET LOCALを使用してパラメータをローカルに設定できます 同じトランザクションで。いいね:

    BEGIN;
    SET LOCAL quote_all_identifiers = true;
    SELECT ...
    END;
    

    より速い

    そうは言っても、私はformat()を使用します およびconcat() カタログテーブルpg_attributeをターゲットにします 代わりに:よりクリーンで、よりシンプルで、より速く。ただし、他のRDBMSには移植できません:

    SELECT format('SELECT %s FROM %s;'
                , string_agg(CASE WHEN atttypid = ANY ('{text, bpchar, varchar}'::regtype[])
                                  THEN concat('left(', col, ', 65535) AS ', col)
                                  ELSE col END, ', ')
                , attrelid)
    FROM  (
       SELECT attrelid::regclass, atttypid, quote_ident(attname) AS col
       FROM   pg_catalog.pg_attribute
       WHERE  attrelid = 'public."MyTableName"'::regclass  -- provide once, optionally schema-qualified
       AND    attnum > 0
       AND    NOT attisdropped
       ORDER  BY attnum
       ) sub
    GROUP  BY attrelid;
    

    生産:

    SELECT id, left(first, 65535) AS first FROM "MyTableName";
    

    db <> fiddle こちら

    特に、...

    • ...テーブル名を指定する必要があるのは1回だけで、オプションでスキーマ修飾されています。
    • ...テーブルが存在しない場合、クエリはすぐに失敗し、役立つエラーメッセージが表示されます。
    • ...出力テーブル名はスキーマ修飾され、必要に応じて二重引用符で囲まれています。
    • ...これにはcharacter(N)も含まれます (内部名bpchar

    さらに読む:




    1. SQL Serverインデックス:主要な要件、パフォーマンスへの影響、および考慮事項

    2. 日時データ型にNOW()値を挿入すると、0000-00-0000:00:00が返されます

    3. 正規表現を使用してMySQLでデータチェックを実施することは可能ですか?

    4. SqlException(0x80131904):無効なオブジェクト名'dbo.Categories'