当前位置: 首页 > 面试题库 >

在PL / pgSQL中使用USING关键字清理用户输入

满俊楠
2023-03-14
问题内容

这就是我创建我的方式search_term

    IF char_length(search_term) > 0 THEN
        order_by := 'ts_rank_cd(textsearchable_index_col, to_tsquery(''' || search_term || ':*''))+GREATEST(0,(-1*EXTRACT(epoch FROM age(last_edited)/86400))+60)/60 DESC';
        search_term := 'to_tsquery(''' || search_term || ':*'') @@ textsearchable_index_col';
    ELSE
        search_term := 'true';
    END IF;

我在使用PLPGSQL函数时遇到了一些麻烦:

    RETURN QUERY EXECUTE '
        SELECT
            *
        FROM
            articles
        WHERE
            $1 AND
            ' || publication_date_query || ' AND
            primary_category LIKE ''' || category_filter || ''' AND
            ' || tags_query || ' AND
            ' || districts_query || ' AND
            ' || capability_query || ' AND
            ' || push_notification_query || ' AND
            ' || distance_query || ' AND
            ' || revision_by || ' AND
            ' || publication_priority_query || ' AND
            ' || status_query || ' AND
            is_template = ' || only_templates || ' AND
            status <> ''DELETED''
        ORDER BY ' || order_by || ' LIMIT 500'
        USING search_term;
    END; $$;

返回错误:

AND的参数必须为布尔型,而不是字符64处的文本

相对于:

        RETURN QUERY EXECUTE '
            SELECT
                *
            FROM
                articles
            WHERE
                ' || search_term || ' AND
                ' || publication_date_query || ' AND
                primary_category LIKE ''' || category_filter || ''' AND
                ' || tags_query || ' AND
                ' || districts_query || ' AND
                ' || capability_query || ' AND
                ' || push_notification_query || ' AND
                ' || distance_query || ' AND
                ' || revision_by || ' AND
                ' || publication_priority_query || ' AND
                ' || status_query || ' AND
                is_template = ' || only_templates || ' AND
                status <> ''DELETED''
            ORDER BY ' || order_by || ' LIMIT 500';
        END; $$;

…有效。我想念什么吗?
我的目标是清理用户输入。


问题答案:

如果某些输入参数可以为 NULL 或为 空, 并且在这种情况下应被忽略,则最好根据用户输入动态地构建整个语句-
并完全省略各自的WHERE/ORDER BY子句。

关键是在此过程中正确,安全(优雅地)处理NULL和空字符串。对于初学者来说,这search_term <>''

您需要对PL / pgSQL有深入的了解,否则您可能会陷入困境。您的案例的示例代码:

CREATE OR REPLACE FUNCTION my_func(
         _search_term            text = NULL  -- default value NULL to allow short call
       , _publication_date_query date = NULL 
    -- , more parameters
       )
  RETURNS SETOF articles AS
$func$
DECLARE
   sql       text;
   sql_order text;   -- defaults to NULL

BEGIN
   sql := concat_ws(' AND '
    ,'SELECT * FROM articles WHERE status <> ''DELETED'''  -- first WHERE clause is immutable
    , CASE WHEN _search_term <> ''            THEN '$1 @@ textsearchable_index_col' END  -- ELSE NULL is implicit
    , CASE WHEN _publication_date_query <> '' THEN 'publication_date > $2'          END  -- or similar ...
 -- , more more parameters
   );

   IF search_term <> '' THEN  -- note use of $1!
      sql_order  := 'ORDER BY ts_rank_cd(textsearchable_index_col, $1) + GREATEST(0,(-1*EXTRACT(epoch FROM age(last_edited)/86400))+60)/60 DESC';
   END IF;

   RETURN QUERY EXECUTE concat_ws(' ', sql, sql_order, 'LIMIT 500')
   USING  to_tsquery(_search_term || ':*')  -- $1  -- prepare ts_query once here!
        , _publication_date_query           -- $2  -- order of params must match!
     -- , more parameters
   ;

END
$func$  LANGUAGE plpgsql;

我为函数参数添加了默认值,因此您可以忽略在调用中不适用的参数。喜欢:

SELECT * FROM my_func(_publication_date_query => '2016-01-01');


 类似资料:
  • 对于PL/pgSQL来说是全新的,这个函数中的双美元符号是什么意思: 我猜,在中,是占位符。 最后一行有点玄机:< code > $ $ LANGUAGE plpgsql STRICT IMMUTABLE; 顺便问一下,最后一行是什么意思?

  • 问题内容: 是否有某个功能全面的功能可以很好地用于清理用户针对SQL注入和XSS攻击的输入,同时仍然允许某些类型的HTML标签? 问题答案: 常见的误解是可以过滤用户输入。PHP甚至有一个(现在已弃用的)“功能”,称为magic-quotes,它基于此思想。废话 忘记过滤(或清洁,或任何人称呼它)。 为避免出现问题,您应该做的事情很简单:每当将字符串嵌入外部代码中时,都必须根据该语言的规则对其进行

  • 问题内容: Java是否具有在休眠状态下打开会话时可以使用的using语句? 在C#中,它类似于: 因此,对象超出范围并自动关闭。 问题答案: Java 7引入了自动资源块管理,该功能将该功能引入了Java平台。Java的早期版本没有任何相似之处。 例如,您可以使用通过以下方式实现的任何变量: 由流实现的Java 接口自动扩展,因此您可以像在C#块中使用流一样使用块中的流。这等效于C#的。 从5.

  • 问题内容: 对来说是全新的,此函数中双美元符号的含义是什么: 我猜想在中是一个占位符。 最后一行有点神秘: ; 顺便说一句,最后一行是什么意思? 问题答案: 美元符号用于美元报价,并且绝不特定于功能定义。它几乎可以在SQL脚本中的任何地方用于替换单引号。 函数的主体恰好是字符串文字,必须用单引号将其引起来。美元报价是PostgreSQL特定于单引号的替代,以避免在函数体内引用问题。您也可以用单引号

  • 问题内容: 当ai遇到关键字时,我正在研究Java中的方法重写。在Internet和其他来源上进行了大量搜索之后,我得出结论,当实例变量的名称与构造函数的参数相同时,将使用关键字。我是对还是错? 问题答案: 是实例中当前实例的别名或名称。它对于消除实例变量与局部变量(包括参数)的区别很有用,但它本身可以用来简单地引用成员变量和方法,调用其他构造函数重载或简单地引用 实例 。适用用途的一些示例(并非

  • 问题内容: 我试图了解java关键字的this实际作用。我一直在阅读Sun的文档,但对于this实际操作仍然不甚了解。 java 关键字 问题答案: 关键字是对当前对象的引用。 另一种思考方式是关键字就像你用来引用自己的人称代词。对于相同的概念,其他语言使用不同的词。VB使用Me和Python约定(因为Python不使用关键字,只是每个方法的隐式参数)将被使用。 如果要引用本质上属于你的对象,你将