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