PostgreSQL中使用DO $$匿名代码块时如何传递参数?
PostgreSQL中使用DO $$匿名代码块时如何传递参数?
嘿,我明白你的困扰——刚接触PostgreSQL就遇到这种参数传递的坑确实烦人!问题出在PostgreSQL的DO匿名代码块不支持直接引用外部的@风格参数,它把你的@Customer_id当成了一个普通的标识符,而不是参数,所以才会报那个“operator does not exist”的错误。
要解决这个问题,你需要通过USING子句把外部参数传递到DO块内部,然后在块里用位置占位符($1、$2这类)或者先把参数赋值给内部变量再使用。下面给你两种可行的修改方案:
方案一:直接在DO块内使用位置占位符
这种方式最简洁,适合参数只用一次的场景:
var query = $@" DO $$ BEGIN IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_schema = CURRENT_SCHEMA AND table_name = 'TableOne') THEN INSERT INTO TableTwo (customer_id, site_id, item_id, qoh) SELECT customer_id, site_id, item_id, qoh FROM TableOne WHERE customer_id = $1; -- 用$1指代USING传递的第一个参数 END IF; END $$ USING @Customer_id;"; -- 通过USING把外部参数传入DO块 await dbConnection.ExecuteAsync(query, new { Customer_id });
方案二:先声明内部变量再使用
如果参数需要多次使用,或者你想让代码更清晰,可以先在DO块里声明变量,把传递进来的参数赋值给它:
var query = $@" DO $$ DECLARE -- 这里的类型要和你的customer_id字段类型一致,比如INT、VARCHAR、UUID等 v_customer_id VARCHAR := $1; BEGIN IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_schema = CURRENT_SCHEMA AND table_name = 'TableOne') THEN INSERT INTO TableTwo (customer_id, site_id, item_id, qoh) SELECT customer_id, site_id, item_id, qoh FROM TableOne WHERE customer_id = v_customer_id; END IF; END $$ USING @Customer_id;"; await dbConnection.ExecuteAsync(query, new { Customer_id });
关键说明:
- DO块是PostgreSQL的匿名过程,它的参数传递规则和普通SQL查询不一样,必须通过
USING子句传入,然后用$n(n是参数位置)来引用。 - 注意变量类型要和你的
customer_id字段类型严格匹配,不然可能会出现类型转换错误。
这样修改后,你的参数就能被正确识别,DO块也能正常执行啦!
备注:内容来源于stack exchange,提问作者Daniele
相关产品推荐
相关产品推荐

