简体   繁体   中英

Embded a delete in select statement in postgres

I am trying to embed a Delete operation in SELECT in postgres. Tried the following command but its not working.. :(

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

where the actual query in TS looks like

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

I'm trying to fit the

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

in the place of '%{filter}%'

I am getting errors all around and not able to perform the operation!

You're trying to execute an invalid SQL statement. If you want to return rows from the delete statement you can use the 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%'

You can use function and lateral achieve that.

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

simple function, use case insensitive regex pattern match to delete rows.

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

Then the following query will do 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');

If I understand your question correctly, you are trying to exploit SQL injection by replacing '%${filter}%' with some sub-query that deletes rows.

You can't have a sub-query that runs a DML statement, but you can use the well known little bobby tables approach to inject a DELETE statement.

Assuming that ${filter} will be replaced at runtime with the value provided, and you pass the following string as the filter parameter:

';delete from tasks where true or title = '

then the query is turned into two queries:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM