PostgreSQL 中带参数的 SQL 视图,防止运行时 SQL 错误的最佳方法?

Posted

技术标签:

【中文标题】PostgreSQL 中带参数的 SQL 视图,防止运行时 SQL 错误的最佳方法?【英文标题】:SQL View with Parameter in PostgreSQL, best way to prevent SQL error on runtime? 【发布时间】:2016-06-22 02:19:53 【问题描述】:

是否可以在PostgreSQL中创建带参数的视图?

问题是,我们的后端服务中可能存在未经验证的 SQL 语法,这可能会导致内部服务器错误,所以我可能需要将每个查询都转换为视图?

类似这样的:

query := ` --
   func Bla_ByType
SELECT id
  , data
    -
    >>
    'name'
FROM bla
WHERE data->>'type' = ` + escapeAndQuote(param1)

上面的语法没有被检测为错误,因为它只是一个字符串,正确的应该是:

query := ` -- func Bla_ByType
SELECT id
  , data->>'name'
FROM bla
WHERE data->>'type' = ` + escapeAndQuote(param1)

上面的例子只是一个简单的查询,其他的比较长,大概是这样:

WITH t AS (
   SELECT ...
   FROM 
   WHERE param1
) SELECT ... 
FROM ...
LEFT JOIN t 
WHERE param2`

除了阅读课还有其他选择吗:

CREATE OR REPLACE VIEW v_bla_bytype AS 
SELECT id
  , data->>'name'
FROM bla
WHERE data->>'type' = CAST(current_setting('bla_bytype._type') as TEXT)

SET bla_bytype._type = 'test';
SELECT * FROM v_bla_bytype;

会话变量的问题仍然会出现错误,例如:ERROR: unrecognized configuration parameter "bla_bytype._type" 如果程序员忘记设置会话变量。

或者使用存储过程:

CREATE OR REPLACE FUNCTION p_bla_bytype(_type text)
RETURNS TABLE (id bigint, name text) AS $$
  SELECT id
  , data->>'name'
  FROM bla
  WHERE data->>'type' = $1 
$$ LANGUAGE sql;
-- i don't know hot to use "_type" by name not using number ($1)

SELECT * FROM p_bla_bytype('test');

存储过程的问题是列名必须输入两次(一次在SELECT,一次在RETURNS),我们还需要声明数据类型。

除了这两个之外,还有其他替代/更短的解决方案吗?可能是这样的:

CREATE OR REPLACE PARAMETERIZED VIEW pv_bla_bytype(_type TEXT) AS
  SELECT id
    , data->>'name' "name"
  FROM bla
  WHERE data->>'type' = $_type
;

SELECT * FROM pv_bla_bytype('test');

解决方案应该有:

性能不错 sql 语法已验证 不要输入太多

PostgreSQL中有这样的解决方案吗?

【问题讨论】:

您无需将查询转换为视图以避免语法错误。你需要测试它们。 为什么不使用函数呢? ***.com/q/11401749/330315 在发布时,您似乎突然制造了一个问题。真正的问题是什么? 真正的问题是从测试的SQL复制粘贴到后端源代码,它会自动格式化,如果后端代码缺少1个引号显然会出错(它会影响下一个SQL语句) 【参考方案1】:

试试功能?..

CREATE OR REPLACE function pv_bla_bytype(_type TEXT) returns table (id bigint, name text) AS 
$F$
declare
begin
return query 
  SELECT bla.id
    , data->>'name' "name"
  FROM bla
  WHERE data->>'type' = _type
;
end;
$F$
language plpgsql
;
SELECT * FROM pv_bla_bytype('test');

【讨论】:

以上是关于PostgreSQL 中带参数的 SQL 视图,防止运行时 SQL 错误的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建指向字段名称中带有句点的 SQL Server 视图的 Jet ODBC 链接?

pl/sql 中带参数的过程

SQL*Plus 中带有多个参数的假脱机输出

PL/SQL 过程中带有 IN OUT 参数的意外结果

PostgreSQL中带/不带时区的时间戳之间的差异

postgresql中带有n的varchar和没有n的varchar [重复]