将PostgreSQL输出参数返回给Python将返回预先提交的值
我有一个存储过程,它可以对客户采集的仪表读数执行很多操作,并且应该在最后重新计算客户的实时余额。这一切都很好,但我想稍微调整一下,如果过程是以交互/同步方式运行的,而不是以批处理模式运行的,则将实时平衡返回给调用者。我实际上传回了两个输出参数:将PostgreSQL输出参数返回给Python将返回预先提交的值,python,postgresql,stored-procedures,Python,Postgresql,Stored Procedures,我有一个存储过程,它可以对客户采集的仪表读数执行很多操作,并且应该在最后重新计算客户的实时余额。这一切都很好,但我想稍微调整一下,如果过程是以交互/同步方式运行的,而不是以批处理模式运行的,则将实时平衡返回给调用者。我实际上传回了两个输出参数: 客户是否因为其读数与估计值相差甚远而被重新收费 客户的新实时余额-根据最近的读数估计,几乎总是会发生变化 我的过程是这样调用的:callstaging.process\u reading\u batch('32f6c6cd-d72c-467c-932
- 客户是否因为其读数与估计值相差甚远而被重新收费
- 客户的新实时余额-根据最近的读数估计,几乎总是会发生变化
callstaging.process\u reading\u batch('32f6c6cd-d72c-467c-932a-31d553ad6f69':uuid,true)代码>,其中第一个参数是唯一的UUID,第二个参数表示我们处于交互模式,希望恢复平衡
我的过程的头块实际上如下所示:
CREATE OR REPLACE PROCEDURE staging.process_reading_batch (
pb_batch_id uuid,
pb_interactive boolean DEFAULT false,
pb_force_validation boolean DEFAULT false,
pb_reprocess boolean DEFAULT false,
pb_logging boolean DEFAULT false,
inout pb_has_cancelled_bills boolean DEFAULT false,
inout pb_live_balance numeric(9,2) DEFAULT 0)
到目前为止一切都很好,除了我没有办法看到我用来运行这个过程的工具的输出值。如果我使用SQL Server(例如),我会声明几个变量,在执行过程时传入这些变量,然后在完成时检查它们。我不知道PostgreSQL是否能做到这一点,但我假设不能做到
相反,我使用Python脚本调用该过程:
# call the stored procedure to interactively process the batch
cursorBilling.execute("CALL staging.process_reading_batch('32f6c6cd-d72c-467c-932a-31d553ad6f69'::uuid, true);")
connectionBilling.commit()
result = cursorBilling.fetchall()
for row in result:
print(row[0])
print(row[1])
这是可行的,但返回的动态平衡不是当前平衡,而是添加新读数之前的平衡。因此,如果客户的活期余额为100.00英镑,我添加了一些读数,他们的余额移动到110.00英镑,那么我将得到返回的活期余额为100.00英镑,即之前的值。第二次运行该过程时,将正确返回live balance,但这只是因为它这次没有更改
我假设发生的情况如下:
- 我加上读数,这是没有承诺的
- 我重新计算了实时余额,但这也没有实现
- 我查询实时余额,并获取提交的(以前的)余额
- 我将此值作为活动余额返回
- 我提交更改,然后更新活动余额
- 我将旧的余额传递回消费者
现在,这是一种过度杀伤力,但在过程中,这是更新活动余额的调用:
-- Recalculate Unbilled
customer_list := ARRAY(SELECT DISTINCT customer_id FROM register_batch_summary_temp);
CALL billing.calculate_unbilled(customer_list, current_date, pb_logging);
-- If this is interactive then we need to set the new balance
IF pb_interactive = true THEN
-- Get the first customer from the array, as there should only be one customer
pb_customer_id := customer_list[1];
SELECT
COALESCE(ub.unbilled_total, 0)
INTO
pb_live_balance
FROM
billing.unbilled_header ub
WHERE
ub.customer_id = pb_customer_id;
END IF;
…这是紧接着返回实时余额的代码:
-- Recalculate Unbilled
customer_list := ARRAY(SELECT DISTINCT customer_id FROM register_batch_summary_temp);
CALL billing.calculate_unbilled(customer_list, current_date, pb_logging);
-- If this is interactive then we need to set the new balance
IF pb_interactive = true THEN
-- Get the first customer from the array, as there should only be one customer
pb_customer_id := customer_list[1];
SELECT
COALESCE(ub.unbilled_total, 0)
INTO
pb_live_balance
FROM
billing.unbilled_header ub
WHERE
ub.customer_id = pb_customer_id;
END IF;
我99%确信,如果我可以调用该过程并直接从作为SQL的一部分运行的过程中返回输出参数,那么这将是可行的,而且我看到的问题仅仅是因为Python对事务做了奇怪的事情
最后,如果我从Python脚本中删除connectionBilling.commit()
,那么我会得到以前的活动余额,而活动余额不会更新,或者添加新的读数,等等