如何在 Postgres 查询窗口中使用参数测试我的 ad-hoc SQL
Posted
技术标签:
【中文标题】如何在 Postgres 查询窗口中使用参数测试我的 ad-hoc SQL【英文标题】:How to test my ad-hoc SQL with parameters in Postgres query window 【发布时间】:2015-07-22 15:39:17 【问题描述】:在 Microsoft SQL Server 中,在查询窗口中测试类似这样的内容:
select * from Users where LastName = @lastname
我可以在命令前加上这个:
declare @lastname varchar(16)
set @lastname = 'Troy'
但在 PostgreSQL 中,我找不到类似的方法。看来我唯一能做的就是直接用它的值替换参数名称。当临时查询变得复杂并且多次使用相同的参数时,这会变得很困难。有什么办法吗?
【问题讨论】:
顺便说一句:“Postgres 查询窗口”?你的意思是 pgAdmin 查询窗口? 我也习惯了 MSSQL 的工作流程,将参数化查询复制到查询运行器中,在其上方设置声明,然后点击运行。这样我就不会在修改它以进行测试的过程中错误地更改查询语义。令人失望的是,在 postgres 中没有办法做到这一点。必须始终更改参数化查询(至少,变量名称或插入转换)来测试它并冒着测试结果无效的风险。 工作流也存在于 mysql 中,使用SET @var = 123
。 ***.com/questions/11754781/…。我知道我在 MSSQL 之前使用过它。
【参考方案1】:
多种选择。
在CTE 中提供参数以在纯SQL中拥有“变量”:
WITH var(lastname) AS (SELECT 'Troy'::varchar(16))
SELECT *
FROM users, var v
WHERE lastname = v.lastname;
这适用于任何查询。
由于 CTE var
包含 单行,因此在 FROM 子句末尾附加 CROSS JOIN
是安全的 - 实际上是附加它的简短形式在逗号之后可能是最好的,因为显式连接语法在逗号之前绑定。额外的表别名v
是可选的以进一步缩短语法。
或不带 CTE 更便宜。顺便说一句,为什么varchar(16)
?只需使用text
:
SELECT *
FROM users
JOIN (SELECT 'Troy'::text) var(lastname) USING (lastname)
WHERE lastname = var.lastname;
或使用临时表为同一会话中的所有查询发挥类似的作用。临时表在会话结束时终止。
CREATE TEMP TABLE var AS
SELECT text 'Troy' AS lastname;
ANALYZE var; -- temp tables are not covered by autovacuum
SELECT * FROM users JOIN var USING (lastname);
About temporary tables and autovacuum
或者您可以使用 DO
语句,如 @Houari 提供的或此处演示的:
请注意,您不能从 DO
语句返回值。 (不过,您可以使用RAISE ...
。)并且您不能在 plpgsql 中使用没有目标的SELECT
- DO
语句中的默认过程语言。将 SELECT
替换为 PERFORM
以丢弃结果。
或者您可以使用customized options,您可以在postgresql.conf
中将其设置为全局可见。
或在您的会话中设置为在会话期间可见并且仅在同一会话中:
SET my.lastname = 'Troy';
变量名必须包含一个点。这种方式仅限于 text
作为数据类型,但任何数据类型都可以表示为 text
...
您可以使用current_setting('my.lastname')
作为值表达式。如果需要,请投射。例如:current_setting('my.json_var')::json
...
或使用SET LOCAL
使效果仅持续当前事务。见:
或者您可以使用微小的IMMUTABLE
函数作为只有特权用户才能操作的全局持久变量。见:
或当使用psql 作为客户端时,使用\set
或\gset
元命令和variable substitution。
【讨论】:
临时表选项给我带来了很多麻烦。这是一个隐式连接,需要在更新子句中使用 FROM,这使得它需要几分钟才能运行。 @Noumenon:注意添加的关于临时表和自动清理的位。【参考方案2】:也许使用DO 指令来模拟一个函数。通过这种方式,您可以声明变量并使用它们来执行您的查询!
http://www.postgresql.org/docs/9.4/static/sql-do.html
【讨论】:
我试过了,但是它总是得到一个 sql 错误:错误:查询没有结果数据的目的地 SQL 状态:42601 提示:如果你想丢弃 SELECT 的结果,请改用 PERFORM。上下文:SQL 语句中的 PL/pgSQL 函数 inline_code_block 第 5 行 DO $$ DECLARE startDate Timestamp; BEGIN startDate := '2014-4-1';从 grouping_horizontal 中选择 pid,其中 dt = startDate;结束 $$; @Carol:提示说明了一切:使用关键字PERFORM
而不是SELECT
。您不能在 DO
语句中没有目标的 SELECT
并且不能返回行...【参考方案3】:
我将postgres配置为记录所有命令,并从日志文件中复制命令,因此所有参数都已替换为值,并在查询窗口中测试命令。
可能不是最好的方法,但它很容易并且对我有用
【讨论】:
以上是关于如何在 Postgres 查询窗口中使用参数测试我的 ad-hoc SQL的主要内容,如果未能解决你的问题,请参考以下文章
使用窗口函数在 Postgres 上使用 SqlAlchemy 限制查询