Dù bằng cách nào, điều đó hoàn toàn có thể , với điều kiện là tất cả các tham số của bạn đều thuộc cùng một loại dữ liệu .
EXECUTE ... USING
vui vẻ nhận một mảng, được coi là một đối số duy nhất . Các phần tử truy cập với các mảng con.
create or replace function test_function(_filter1 text = null
, _filter2 text = null
, OUT retid int) as
$func$
declare
_args text[] := ARRAY[_filter1, _filter2];
_wher text[];
begin
if _filter1 is not null then
_wher := _wher || 'parameter_name = $1[1]'; -- note array subscript
end if;
if _filter2 is not null then
_wher := _wher || 'parameter_name = $1[2]'; -- assign the result!
end if;
IF _args IS NULL -- check whether all params are NULL
RAISE EXCEPTION 'At least one parameter required!';
END IF;
execute 'select id from mytable where ' -- cover case with all params NULL
|| array_to_string(_wher, ' or ')
|| ' ORDER BY id LIMIT 1'; -- For a single value (???)
into retid
using _args;
end
$func$ language plpgsql;
Đây chỉ là một bằng chứng về khái niệm và phức tạp không cần thiết. Nó sẽ là một tùy chọn thú vị cho đầu vào mảng thực tế , ví dụ với một VARIADIC
hàm .
Đối với trường hợp trong tầm tay, sử dụng thay thế:
CREATE OR REPLACE FUNCTION test_function(_filter1 text = null
, _filter2 text = null)
RETURNS SETOF int AS
$func$
DECLARE
_wher text := concat_ws(' OR '
, CASE WHEN _filter1 IS NOT NULL THEN 'parameter_name = $1' END
, CASE WHEN _filter2 IS NOT NULL THEN 'parameter_name = $2' END);
BEGIN
IF _wher = '' -- check whether all params are NULL
RAISE EXCEPTION 'At least one parameter required!';
END IF;
RETURN QUERY EXECUTE 'SELECT id FROM mytable WHERE ' || _wher
USING $1, $2;
-- USING _filter1 , filter2; -- alternatively use func param names
END
$func$ LANGUAGE plpgsql;
Giải thích
Liệt kê tất cả các giá trị có thể có thể được tham chiếu trong truy vấn động trong USING
mệnh đề theo thứ tự xuất hiện của chúng. Nếu không phải tất cả chúng sẽ được tham chiếu trong truy vấn động, thì không có hại gì trong đó. Nhưng chúng ta cần giữ nguyên vị trí thứ tự .
Đặc biệt lưu ý rằng bên trong các tham chiếu truy vấn động đã cho các giá trị của mệnh đề theo số thứ tự, trong khi trong các tham số hàm tham chiếu mệnh đề . Cùng một cú pháp, phạm vi khác nhau!
Trong ví dụ của tôi tham khảo cho đơn giản. Nhưng người ta có thể sắp xếp lại các giá trị trong mệnh đề theo bất kỳ cách nào, sao cho (ví dụ) trong tham chiếu truy vấn động ở vị trí thứ 2 trong mệnh đề, tham chiếu tham số hàm số 1.$n
USING
$n
USING
$2
$2
USING
$2
$1
USING
Điều này cho phép bất kỳ số lượng tham số với bất kỳ loại dữ liệu (không đồng nhất) .
Trả về một tập hợp số nguyên trong ví dụ này ( RETURNS SETOF int
), phù hợp hơn với ví dụ - sử dụng RETURN QUERY EXECUTE
tương ứng.
concat_ws()
đặc biệt tiện dụng để tập hợp một danh sách các vị từ OR'ed hoặc AND'ed một cách có điều kiện.
EXECUTE ... USING
không thể lấy một loạt các đối số, vì các mảng PostgreSQL không hỗ trợ các kiểu hetrogenous. Chúng phải là một mảng của một loại cụ thể và SQL có thể không có cùng loại cho mỗi tham số. Nó sẽ vô dụng trừ những trường hợp sử dụng rất hẹp. Thay vào đó,USING
sẽ phải có thể lấy một bản ghi ẩn danh, giống như bạn tạo từ một nhàROW(...)
xây dựng ... điều này có thể có thể, nhưng hiện không được thực hiện.