计算受 plpgsql 函数影响的行数

Count the rows affected by plpgsql function(计算受 plpgsql 函数影响的行数)
本文介绍了计算受 plpgsql 函数影响的行数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我有以下功能:

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 一起使用:

I use this with PHP PDO:

$stmt = $pdo->prepare('SELECT * FROM user_delete(?)');
$stmt->execute(array($user['id']));

结果包含现在

array(
    array('user_delete' => '')
)

所以

$stmt->rowCount();

总是一个.

是否可以解决这个问题:通过函数不返回任何内容(因为它是无效的),并且通过 rowCount 返回受影响行的计数?

Is it possible to fix this: by the function return nothing (because it is void), and by the rowCount return the count of the affected rows?

解决方案:

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 就没有必要了...

I can achieve return zero length result with setof void return type, but that is not necessary if I force it to throw PDOException when the resource is not found ...

推荐答案

您可以使用:

GET DIAGNOSTICS integer_var = ROW_COUNT;

.. 并让函数返回计数.手册中的详细信息.

.. and let the function return the 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;

您将此作为第一个声明:

You had this as 1st statement:

SELECT * FROM "user" WHERE user_id = $1 FOR UPDATE;

无效语法 - 在 plpgsql 函数中,您需要将 PERFORM 用于没有目标的 SELECT 语句:

Invalid syntax - inside a plpgsql function you need to use PERFORM for SELECT statements without target:

PERFORM * FROM "user" WHERE user_id = $1 FOR UPDATE;

  • SELECT 在 PL/pgSQL 函数中引发异常
  • 但随后的 DELETE 语句也同样锁定该行.不需要 使用 为更新开始.

    But the ensuing DELETE statement locks the row just as well. No need for manual locking with FOR UPDATE to begin with.

    添加的OUT del_ct int 声明了一个OUT 参数,该参数可以像任何变量一样赋值,并在函数结束时自动返回.它还消除了对显式 RETURNS 声明的需要.

    The added OUT del_ct int declares an OUT parameter that can be assigned like any variable and is returned at the end of the function automatically. It also obviates the need for an explicit RETURNS declaration.

    这篇关于计算受 plpgsql 函数影响的行数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

    本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

DeepL的翻译效果还是很强大的,如果我们要用php实现DeepL翻译调用,该怎么办呢?以下是代码示例,希望能够帮到需要的朋友。 在这里需要注意,这个DeepL的账户和api申请比较难,不支持中国大陆申请,需要拥有香港或者海外信用卡才行,没账号的话,目前某宝可以
PHP通过phpspreadsheet导入Excel日期,导入系统后,全部变为了4开头的几位数字,这是为什么呢?原因很简单,将Excel的时间设置问文本,我们就能看到该日期本来的数值,上图对应的数值为: 要怎么解决呢?进行数据转换就行,这里可以封装方法,或者用第三方的
mediatemple - can#39;t send email using codeigniter(mediatemple - 无法使用 codeigniter 发送电子邮件)
Laravel Gmail Configuration Error(Laravel Gmail 配置错误)
Problem with using PHPMailer for SMTP(将 PHPMailer 用于 SMTP 的问题)
Issue on how to setup SMTP using PHPMailer in GoDaddy server(关于如何在 GoDaddy 服务器中使用 PHPMailer 设置 SMTP 的问题)