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

PostgreSQL中带参数的SQL视图,防止运行时出现SQL错误的最佳方法?,sql,postgresql,sql-view,Sql,Postgresql,Sql View,是否可以在PostgreSQL中使用参数创建视图 问题是,我们的后端服务中可能存在未经验证的SQL语法,这可能会导致内部服务器错误,所以我可能需要将每个查询转换为视图 大概是这样的: query := ` -- func Bla_ByType SELECT id , data - >> 'name' FROM bla WHERE data->>'type' = ` + escapeAndQuote(param1) WITH t AS (

是否可以在PostgreSQL中使用参数创建视图

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

大概是这样的:

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`
上述语法未检测为错误,因为它只是一个字符串,正确的语法为:

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;
会话变量的问题仍然是,如果程序员忘记设置会话变量,将出现错误,例如:
错误:无法识别的配置参数“bla_bytype.\u 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');
存储过程的问题是列名必须键入2次(一次在
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中有这样的解决方案吗?

try function

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');
尝试函数

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');

您不需要将查询转换为视图以避免语法错误。你需要测试它们。为什么不使用函数呢?当它被张贴出来时,它看起来像是你无中生有地制造了一个问题。真正的问题是什么?真正的问题是当从测试过的SQL复制粘贴到后端源代码时,它会自动格式化,如果后端代码缺少1个引号(它会影响下一个SQL语句),则显然会出错。您不需要将查询转换为视图以避免语法错误。你需要测试它们。为什么不使用函数呢?当它被张贴出来时,它看起来像是你无中生有地制造了一个问题。真正的问题是什么?真正的问题是从测试的SQL复制粘贴到后端源代码时,它会自动格式化,如果后端代码缺少1个引号,显然会出错(这会影响下一个SQL语句)