【问题标题】:Embded a delete in select statement in postgres在 postgres 的 select 语句中嵌入删除
【发布时间】:2022-12-18 00:10:08
【问题描述】:

我正在尝试在 postgres 的 SELECT 中嵌入删除操作。尝试了以下命令但它不起作用.. :(

select * from tasks where title ilike '% 
Delete from tasks where title ilike `%Re%` returning ( 
Select title from tasks where title ilike `%smoke%`)%'

TS 中的实际查询看起来像

select * from tasks where title ilike '%${filter}%'

我正在努力适应

Delete from tasks where title ilike '%Re%' returning ( 
Select title from tasks where title ilike '%smoke%') 

代替 '%{filter}%'

我到处都是错误,无法执行操作!

【问题讨论】:

  • 所写的 returning 子句没有意义。它不接受子查询。您只能指定要返回的列列表。你到底想用它达到什么目的?
  • 我正在尝试对使用 Nest.js 构建的表单进行 SQL 注入测试。此表单使用 select * from tasks where title like '%${filter}%' 查询后端。这里的过滤器是从前端发送的查询参数

标签: sql postgresql sql-delete


【解决方案1】:

您正在尝试执行无效的 SQL 语句。如果你想从删除语句中返回行,你可以使用CTE

WITH del AS (
   -- it will be better to get the task id here
   DELETE FROM tasks WHERE title ILIKE '%Re%' RETURNING title
)
   SELECT title FROM del WHERE title ILIKE '%smoke%'

【讨论】:

    【解决方案2】:

    您可以使用功能和横向实现。

    CREATE temp TABLE tasks (
        title text
        , misc numeric DEFAULT random() ::numeric
    );
    INSERT INTO tasks (title)
        VALUES ('foo bar');
    INSERT INTO tasks (title)
        VALUES ('Re')
        , ('Re_1')
        , ('smoke_1')
        , ('smoke_2')
        , ('smoke_3')
        , ('foo bar')
        , ('brown');'
    

    简单的功能,使用不区分大小写的正则表达式模式匹配来删除行。

    CREATE OR REPLACE FUNCTION delete_tasks_title_pattern (x text)
        RETURNS void
        AS $func$
        DELETE FROM tasks
        WHERE title ~* x;
    $func$
    LANGUAGE sql
    STRICT;
    

    然后下面的查询将执行 select (title ILIKE '%smoke%') and delete (title ~* 'foo')

    SELECT
        sub.*
    FROM (
        SELECT
            *
        FROM
            tasks
        WHERE
            title ILIKE '%smoke%') sub
        , LATERAL delete_tasks_title_pattern ('foo');
    

    【讨论】:

      【解决方案3】:

      如果我正确理解你的问题,你正试图通过将 '%${filter}%' 替换为一些删除行的子查询来利用 SQL 注入。

      您不能拥有运行 DML 语句的子查询,但可以使用众所周知的 little bobby tables 方法来注入 DELETE 语句。

      假设 ${filter} 将在运行时替换为提供的值,并且您将以下字符串作为过滤器参数传递:

      ';delete from tasks where true or title = '
      

      然后查询变成两个查询:

      select * from tasks where title ilike '%';
      delete from tasks where true or title = '%'
      

      【讨论】:

        猜你喜欢
        • 2013-08-04
        • 1970-01-01
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 2010-09-12
        • 2021-05-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多