PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

quote_ident () không thêm dấu ngoặc kép vào tên cột trước

Đừng bỏ qua AS từ khóa cho bí danh cột

Không chính xác. Nó nổ tung vì bạn đã bỏ qua từ khóa AS nơi không nên bỏ qua nó.

Điều này hoạt động:

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;

Sản xuất:

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

Lần lượt hoạt động như mong đợi.

hướng dẫn về "Bỏ qua AS Key Word " :

Có thể bỏ qua từ khóa AS cho bí danh bảng, nhưng không cho bí danh cột.

first không phải là từ dành riêng trong Postgres. (Nó từng được "dành riêng" trong SQL-92 tiêu chuẩn SQL cổ, nhưng không còn trong SQL tiêu chuẩn nữa.) Nó là "không dành riêng" * để được chính xác. Hướng dẫn sử dụng :

Bỏ qua AS làm cho nó chỉ là một bối cảnh.

quote_ident() hoạt động đáng tin cậy. Hướng dẫn:

format() với mã xác định %I cũng tương tự.

Các từ dành riêng không được đề cập, nhưng được trích dẫn đúng cách bất kể. Nói chính xác:tất cả các từ khóa được đánh dấu "dành riêng" hoặc "(không thể là chức năng hoặc kiểu)" trong cột "PostgreSQL" của the Các từ khóa trong SQL bảng .

Tôi sẽ gửi một lỗi tài liệu để thêm lỗi đó.

Để hoàn toàn chắc chắn: quote_all_identifiers

Nếu bạn muốn hoàn toàn chắc chắn và không bận tâm đến tất cả những tiếng ồn thêm vào, bạn có thể buộc Postgres trích dẫn tất cả số nhận dạng có tham số cấu hình quote_all_identifiers . Hướng dẫn sử dụng:

Điều đó bao gồm đầu ra từ quote_ident()format() . Tôi sẽ không làm điều đó, tránh tất cả những tiếng ồn thêm vào.

Bạn có thể đặt thông số cục bộ bằng SET LOCAL trong cùng một giao dịch. Như:

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

Nhanh hơn

Điều đó nói rằng, tôi sẽ sử dụng format()concat() và nhắm mục tiêu bảng danh mục pg_attribute thay vào đó:sạch hơn, đơn giản hơn, nhanh hơn. Nhưng không di động đến RDBMS khác:

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;

Sản xuất:

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

db <> fiddle tại đây

Đáng chú ý, ...

  • ... bạn chỉ cần cung cấp tên bảng một lần, tùy chọn đủ điều kiện giản đồ.
  • ... nếu bảng không tồn tại, truy vấn không thành công ngay lập tức với một thông báo lỗi hữu ích.
  • ... tên bảng đầu ra chỉ đủ điều kiện giản đồ và được trích dẫn kép khi cần thiết.
  • ... điều này cũng bao gồm character(N) (tên nội bộ bpchar ).

Đọc thêm:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tính tổng cột thời gian trong PostgreSql

  2. Gây ra bởi:org.postgresql.util.PSQLException:FATAL:các khe kết nối còn lại được dành riêng cho các kết nối siêu người dùng không sao chép

  3. Cách bật Truy vấn Postgis trong Spark SQL

  4. PostgreSQL - Làm cách nào để chèn chuỗi hình ảnh Base64 vào cột BYTEA?

  5. Có gì mới trong PostgreSQL 13?