我有以下功能:
CREATE FUNCTION user_delete(IN id INT4)
RETURNS VOID
AS
$BODY$
BEGIN
SELECT * FROM "user" WHERE user_id = id FOR UPDATE;
DELETE FROM user_role WHERE user_id = id;
DELETE FROM user_permission WHERE user_id = id;
DELETE FROM permission_cache WHERE user_id = id;
DELETE FROM access WHERE user_id = id;
DELETE FROM "user" WHERE user_id = id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
我在PHP PDO中使用它:
$stmt = $pdo->prepare('SELECT * FROM user_delete(?)');
$stmt->execute(array($user['id']));
结果现在包含
array(
array('user_delete' => '')
)
等
$stmt->rowCount();
总是一个。
是否有可能解决这个问题:函数返回什么(因为它是无效的),并且由rowCount返回受影响行的计数?
解决方案:
PHP:
public function delete($id)
{
try {
$this->__call('user_delete', array($id));
} catch (\PDOException $e) {
if ($e->getCode() === 'UE404')
throw new NotFoundException();
else
throw $e;
}
}
SQL:
CREATE FUNCTION user_delete(IN id INT4)
RETURNS VOID
AS
$BODY$
BEGIN
DELETE FROM user_role WHERE user_id = id;
DELETE FROM user_permission WHERE user_id = id;
DELETE FROM permission_cache WHERE user_id = id;
DELETE FROM access WHERE user_id = id;
DELETE FROM "user" WHERE user_id = id;
IF NOT FOUND THEN
RAISE SQLSTATE 'UE404' USING MESSAGE = 'not found for delete';
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
我可以使用setof void
返回类型获得返回零长度的结果,但是如果我在找不到资源时强制它抛出PDOException
,则没有必要...
答案 0 :(得分:1)
您可以使用:
GET DIAGNOSTICS integer_var = ROW_COUNT;
..让函数返回计数。 Details in the manual.
示例:
CREATE OR REPLACE FUNCTION user_delete(id int, OUT del_ct int) AS
$func$
DECLARE
i int; -- helper var
BEGIN
DELETE FROM user_role WHERE user_id = $1;
GET DIAGNOSTICS del_ct = ROW_COUNT; -- init
DELETE FROM user_permission WHERE user_id = $1;
GET DIAGNOSTICS i = ROW_COUNT; del_ct := del_ct + i;
DELETE FROM permission_cache WHERE user_id = $1;
GET DIAGNOSTICS i = ROW_COUNT; del_ct := del_ct + i;
DELETE FROM access WHERE user_id = $1;
GET DIAGNOSTICS i = ROW_COUNT; del_ct := del_ct + i;
DELETE FROM "user" WHERE user_id = $1;
GET DIAGNOSTICS i = ROW_COUNT; del_ct := del_ct + i;
END
$func$ LANGUAGE plpgsql;
你有这个作为第一个声明:
SELECT * FROM "user" WHERE user_id = $1 FOR UPDATE;
语法无效 - 在plpgsql函数中,您需要将PERFORM
用于没有目标的SELECT
语句:
PERFORM * FROM "user" WHERE user_id = $1 FOR UPDATE;
但随后的DELETE
语句也会锁定行。无需manual locking with FOR UPDATE
开始。
添加的OUT del_ct int
声明OUT
参数,可以像任何变量一样分配,并在函数结束时自动返回。它也不需要明确的RETURNS
声明。