我有一些伪代码的混合,其中包括一些PostgresSQL。我想做一个SELECT,基于这个结果集,我想循环遍历这些结果并在这个结果集中做一个嵌套循环,并从中做INSERT
。关于我如何接近这一点的任何指导/建议都会很棒:
# Old CommissionExpenses do not have the cost_item_id set
# New CommissionExpenses have the cost_item_id and purchase_id set
# Find _new_ commissions
results = SELECT * FROM nok.commission_expenses ce WHERE ce.cost_item_id IS NOT NULL AND ce.purchase_id IS NOT NULL
# Loop through those and look up transactions
for result in results
transactions = SELECT * FROM transactions t WHERE t.target_id::integer = result.purchase_id
for t in transactions
INSERT INTO transactions
nextval('transactions_id_seq'::regclass) as id,
t.user_id,
t.transaction_type,
t.account,
result.amount as amount,
result.id as target_id,
t.target_type,
t.created_at,
t.updated_at,
t.log_id
;
从语法上讲我知道这是错的,但我只是想突出以上内容来表达我想要在高层次上实现的目标。我知道Postgres确实支持FOR
循环,并且也尝试在下面自己执行此操作:
CREATE OR REPLACE FUNCTION loop_and_create()
RETURNS VOID AS $$
DECLARE
rec RECORD;
txt RECORD;
BEGIN
FOR rec IN EXECUTE 'SELECT * FROM nok.commission_expenses ce WHERE ce.cost_item_id IS NOT NULL AND ce.purchase_id IS NOT NULL'
LOOP
FOR tx IN EXECUTE 'SELECT * FROM transactions t WHERE t.target_id::integer = rec.purchase_id'
LOOP
INSERT INTO transactions
nextval('transactions_id_seq'::regclass) as id,
tx.user_id,
tx.transaction_type,
tx.account,
rec.amount as amount,
rec.id as target_id,
tx.target_type,
tx.created_at,
tx.updated_at,
tx.log_id
;
END LOOP;
END LOOP;
END;
$$ LANGUAGE plpgsql;
答案 0 :(得分:0)
RDMS用于对集合进行操作。你不需要自己做这件事
INSERT INTO transactions (...)
SELECT t.a, t.b, ...
FROM transactions t, nok.commission_expenses ce
WHERE t.target_id::integer = ce.purchase_id
AND ce.cost_item_id IS NOT NULL
AND ce.purchase_id IS NOT NULL
答案 1 :(得分:0)
执行时
data_list
FOR tx IN EXECUTE 'SELECT *
FROM transactions t
WHERE t.target_id::integer = rec.purchase_id'
应该是变量。
IIRC的语法是:
rec.purchase_id
但是......这不是可行的方法:)
您真正想要的是使用FOR tx IN EXECUTE 'SELECT *
FROM transactions t
WHERE t.target_id = ?'
USING rec. purchase_id
并使用单个语句替换您的整个函数,例如(免责声明:未对此进行测试):
insert ... select ...
它会更快(因为db执行一个查询而不是t_transactions中每行加一个)并且无比容易测试/调试(只需注释掉insert into transactions(id, user_id, transaction_type, account, amount, target_id, target_type, created_at, updated_at, log_id)
select nextval('transactions_id_seq'::regclass) as id,
tx.user_id,
tx.transaction_type,
tx.account,
rec.amount as amount,
rec.id as target_id,
tx.target_type,
tx.created_at,
tx.updated_at,
tx.log_id
from transactions tx
join nok.commission_expenses ce
on ce.purchase_id = tx.target_id
where ce.cost_item_id is not
行,你就可以了能够看到完全,如果要插入的查询与你期望的相符,那么。
PS:您在insert
中为同一个表中的现有行插入新行似乎很可疑......您确定不想更新吗?改为现有的行?