2010-01-20 27 views
6

Tôi đang cố gắng viết một hàm trong PL/PgSQL phải làm việc với một bảng mà nó nhận được dưới dạng tham số.EXECUTE ... Tuyên bố USING trong PL/pgSQL không hoạt động với loại bản ghi?

Tôi sử dụng câu lệnh EXECUTE..INTO..USING trong định nghĩa hàm để tạo truy vấn động (đó là cách duy nhất tôi biết để làm điều này) nhưng ... Tôi gặp sự cố với loại dữ liệu RECORD.

Hãy xem xét ví dụ sau (cực kỳ đơn giản).

-- A table with some values. 
DROP TABLE IF EXISTS table1; 
CREATE TABLE table1 (
    code INT, 
    descr TEXT 
); 

INSERT INTO table1 VALUES ('1','a'); 
INSERT INTO table1 VALUES ('2','b'); 


-- The function code. 
DROP FUNCTION IF EXISTS foo (TEXT); 
CREATE FUNCTION foo (tbl_name TEXT) RETURNS VOID AS $$ 
DECLARE 
    r RECORD; 
    d TEXT; 
BEGIN 
    FOR r IN 
    EXECUTE 'SELECT * FROM ' || tbl_name 
    LOOP 
    --SELECT r.descr INTO d; --IT WORK 
    EXECUTE 'SELECT ($1)' || '.descr' INTO d USING r; --IT DOES NOT WORK 
    RAISE NOTICE '%', d; 
END LOOP; 

END; 
$$ LANGUAGE plpgsql STRICT; 

-- Call foo function on table1 
SELECT foo('table1'); 

Nó ra các lỗi sau:

ERROR: could not identify column "descr" in record data type

mặc dù cú pháp tôi sử dụng dường như có giá trị đối với tôi. Tôi không thể sử dụng lựa chọn tĩnh (nhận xét trong ví dụ) vì tôi muốn tham khảo một cách thực tế các tên cột.

Vì vậy, có ai đó biết điều gì sai với mã ở trên không?

Trả lời

7

Đó là sự thật. Bạn không thể sử dụng bản ghi loại bên ngoài không gian PL/pgSQL.

Giá trị RECORD chỉ hợp lệ trong plpgsql.

bạn có thể làm

EXECUTE 'SELECT $1.descr' INTO d USING r::text::xx; 
+0

Mã của bạn không hoạt động. – Hobbes

+3

Ok xin lỗi, rõ ràng mã của bạn hoạt động bằng cách thay thế 'xx' bằng 'table1'. Nhưng theo cách đó tôi không thể chỉ rõ tên bảng. Vì vậy, câu trả lời đúng là: "EXECUTE 'SELECT $ 1 :: text :: table1.descr' INTO d USING r;". CẢM ƠN RẤT NHIỀU! – Hobbes

3

$1 nên bên trong ||, như || $1 || và cung cấp cho không gian đúng cách thì nó sẽ làm việc.

BEGIN 

EXECUTE ' delete from ' || quote_ident($1) || ' where condition '; 

END; 
+0

Vấn đề được đề cập là làm thế nào để có được một trường RECORD theo cách _reflective_ (theo tên, sử dụng nối chuỗi). – botchniaque

Các vấn đề liên quan