2009-12-23 31 views
24

Tôi đang cố gắng sử dụng một hàm với PostgreSQL để lưu một số dữ liệu. Đây là kịch bản tạo:Cách gọi một hàm, PostgreSQL

-- Function: "saveUser"(integer, character varying, character varying, character varying, character varying, character varying) 

-- DROP FUNCTION "saveUser"(integer, character varying, character varying, character varying, character varying, character varying); 

CREATE OR REPLACE FUNCTION "saveUser"("pUserID" integer, "pName" character varying, "pLastName" character varying, "pUserName" character varying, "pPassword" character varying, "peMail" character varying) 
    RETURNS boolean AS 
$BODY$ 
BEGIN 
SELECT 1 
FROM "USERS" 
WHERE "userID" = $1; 

IF FOUND THEN 
UPDATE "USERS" 
    SET  "name" = $2, 
    "lastName" = $3, 
    "userName" = $4, 
    "password" = $5, 
    "eMail" = $6 
WHERE "userID" = $1; 
ELSE 
    INSERT INTO "USERS" 
    ("name", "lastName", "userName", "password", "eMail") 
    VALUES 
     ($2, $3, $4, $5, $6); 
END IF; 
END;$BODY$ 
    LANGUAGE 'plpgsql' VOLATILE 
    COST 100; 
ALTER FUNCTION "saveUser"(integer, character varying, character varying, character varying, character varying, character varying) OWNER TO postgres; 

PostreSQL Tài liệu tuyên bố rằng để gọi hàm không trả về bất kỳ kết quả nào, chỉ có thể viết tên và thuộc tính của nó. Vì vậy, tôi cố gắng gọi hàm như thế này:

"saveUser"(3, 'asd','asd','asd','asd','asd'); 

Nhưng tôi nhận được báo lỗi dưới đây:

ERROR: syntax error at or near ""saveUser"" 
LINE 1: "saveUser"(3, 'asd','asd','asd','asd','asd') 
    ^

********** Error ********** 

ERROR: syntax error at or near ""saveUser"" 
SQL state: 42601 
Character: 1 

tôi có các chức năng khác mà trả về một resultset. Tôi sử dụng SELECT * FROM "fnc"(...) để gọi cho họ và nó hoạt động. Tại sao tôi nhận được lỗi này?


EDIT: Tôi đang sử dụng công cụ pgAdmin III Query và cố gắng để thực hiện các câu lệnh SQL ở đó.

Trả lời

36

Cuộc gọi chức năng vẫn phải là một câu lệnh SQL hợp lệ:

SELECT "saveUser"(3, 'asd','asd','asd','asd','asd'); 
+0

Sử dụng điều này, tôi gặp lỗi; "LRI: truy vấn không có đích cho dữ liệu kết quả". Tôi tự hỏi nếu lỗi này có một cái gì đó để làm với tôi muốn trả lại một boolean? –

+0

Tôi đã thử điều này với một hàm khác trả về void và nó hoạt động, nhưng nếu tôi muốn trả về boolean thì sao? –

+2

Erkan: Đã thử kết hợp hai câu trả lời? I E. lời gọi của bạn là sai, và bạn không trả lại bất cứ điều gì cho một hàm được kỳ vọng trả về bool. Hơn nữa, tại sao bạn lại có số nhận dạng chữ hoa chữ thường phải báo giá mọi lúc? –

0

bạn khai báo hàm của bạn là trả về boolean, nhưng nó không bao giờ trả về bất kỳ thứ gì.

+0

tôi chèn dòng, 'RETURN 1 = 1' ở dưới cùng của định nghĩa hàm chỉ để kiểm tra điều này, đã làm không tốt. –

+1

Đúng, nhưng sự cố được báo cáo không phải do điều đó. –

4

nếu chức năng của bạn không muốn quay trở lại bất cứ điều gì bạn nên khai báo với "trả về void" và sau đó bạn có thể gọi nó như thế này "thực hiện functionName (tham số ...); "

+0

Điều này không hiệu quả đối với tôi –

1

Tôi đã gặp vấn đề tương tự khi thử nghiệm một hàm rất giống với sử dụng câu lệnh SELECT để quyết định xem INSERT hay CẬP NHẬT nên được thực hiện. Hàm này đã viết lại một thủ tục lưu sẵn T-SQL.
Khi tôi kiểm tra chức năng từ cửa sổ truy vấn, tôi nhận được lỗi "truy vấn không có đích cho dữ liệu kết quả". Cuối cùng tôi đã tìm ra rằng bởi vì tôi đã sử dụng câu lệnh SELECT bên trong hàm mà tôi không thể kiểm tra hàm từ cửa sổ truy vấn cho đến khi tôi gán các kết quả của SELECT cho một biến cục bộ bằng cách sử dụng câu lệnh INTO. Điều này đã khắc phục được sự cố.

Nếu chức năng ban đầu trong chủ đề này đã được thay đổi như sau nó sẽ làm việc khi gọi từ cửa sổ truy vấn,

$BODY$ 
DECLARE 
    v_temp integer; 
BEGIN 
SELECT 1 INTO v_temp 
FROM "USERS" 
WHERE "userID" = $1; 
7

Đối với PostgreSQL bạn có thể sử dụng PERFORM. PERFORM chỉ hợp lệ trong ngôn ngữ thủ tục PL/PgSQL.

DO $$ BEGIN 
    PERFORM "saveUser"(3, 'asd','asd','asd','asd','asd'); 
END $$; 

Các gợi ý từ nhóm postgres:

HINT: If you want to discard the results of a SELECT, use PERFORM instead.

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