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

Cập nhật nhiều cột bắt đầu bằng một chuỗi cụ thể

Bạn cần SQL động cho việc này. Vì vậy, bạn phải chuẩn bị để đối phó với việc chèn SQL có thể xảy ra.

Truy vấn cơ bản

Truy vấn cơ bản để tạo lệnh DML cần thiết có thể giống như sau:

SELECT format('UPDATE tbl SET (%s) = (%s)'
               ,string_agg (quote_ident(attname), ', ')
               ,string_agg ('NULL', ', ')
             )
FROM   pg_attribute
WHERE  attrelid = 'tbl'::regclass
AND    NOT attisdropped 
AND    attnum > 0
AND    attname ~~ 'foo_%';

Lợi nhuận:

UPDATE tbl SET (foo_a, foo_b, foo_c) = (NULL, NULL, NULL);
  • Tôi sử dụng " cú pháp danh sách cột "trong tổng số UPDATE để rút ngắn mã và đơn giản hóa tác vụ.

  • Tôi truy vấn danh mục hệ thống thay vì giản đồ thông tin bởi vì phần mềm thứ hai, mặc dù được tiêu chuẩn hóa và đảm bảo có thể di động trên các phiên bản chính, nhưng cũng nổi tiếng là chậm và đôi khi khó sử dụng. Có những ưu và khuyết điểm, chúng tôi đã thảo luận điều này nhiều lần ở đây trên SO. Tìm kiếm các từ khóa để biết thêm thông tin.

  • quote_ident() đối với tên cột ngăn chặn SQL-injection và cũng cần thiết cho bất kỳ tên cột không chuẩn.

  • Bạn đã quên đề cập đến phiên bản Postgres của mình. Hàm tổng hợp string_agg() yêu cầu 9.0+.

Tự động hóa hoàn toàn với hàm PL / pgSQL

CREATE OR REPLACE FUNCTION f_update_cols(_tbl regclass, _col_pattern text
                                        , OUT row_ct int, OUT col_ct int)
  RETURNS record AS
$func$
DECLARE
   _sql text;
BEGIN
   SELECT format('UPDATE tbl SET (%s) = (%s)'
                 ,string_agg (quote_ident(attname), ', ')
                 ,string_agg ('NULL', ', ')
                )
         ,count(*)::int
   INTO   _sql, col_ct
   FROM   pg_attribute
   WHERE  attrelid = _tbl
   AND    NOT attisdropped         -- no dropped columns
   AND    attnum > 0               -- no system columns
   AND    attname ~~ _col_pattern; -- only columns matching pattern

   -- RAISE NOTICE '%', _sql;      -- output generated SQL for debugging
   EXECUTE _sql;

   GET DIAGNOSTICS row_ct = ROW_COUNT;
END
$func$  LANGUAGE plpgsql;

COMMENT ON FUNCTION f_update_cols(regclass, text)
 IS 'Updates all columns of table _tbl ($1)
that match _col_pattern ($2) in a LIKE expression.
Returns the count of columns (col_ct) and rows (row_ct) affected.';

Gọi:

SELECT * FROM f_update_cols('myschema.tbl', 'foo%');
  • Để làm cho chức năng thực tế hơn, nó trả về thông tin như được mô tả trong nhận xét. Tìm hiểu thêm về lấy trạng thái kết quả trong plpgsql trong sách hướng dẫn.

  • Tôi sử dụng biến _sql giữ chuỗi truy vấn, vì vậy tôi có thể thu thập số cột được tìm thấy (col_ct ) trong cùng một truy vấn.

  • Loại mã định danh đối tượng regclass là cách hiệu quả nhất để tự động tránh việc chèn SQL (và khử trùng các tên không chuẩn) cho tên bảng. Bạn có thể sử dụng tên bảng đủ điều kiện giản đồ để tránh sự mơ hồ. Tôi khuyên bạn nên làm như vậy nếu bạn có nhiều lược đồ trong db của mình! Thông tin chi tiết về câu hỏi liên quan này:
    Tên bảng dưới dạng tham số hàm PostgreSQL

-> SQLfiddle demo .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách tính tổng có điều kiện hai cột trong PostgreSQL 9.3

  2. Các chuỗi không bị ảnh hưởng bởi các giao dịch?

  3. PostgreSQL COPY CSV với hai chuỗi NULL

  4. PostgreSQL - Gán giá trị số nguyên cho chuỗi trong câu lệnh trường hợp

  5. Tổng quan về Tham số kết nối sslpassword của PostgreSQL 13 libpq