在Postgresql存储过程中使用准备好的语句或动态命令?

时间:2019-05-10 07:01:55

标签: postgresql stored-procedures prepared-statement sql-injection

我正在学习Postgreslq,并且对此代码示例有疑问:

CREATE OR REPLACE PROCEDURE CreateProject(
IN projectName VARCHAR(45),
IN projectYear SMALLINT)
LANGUAGE plpgsql
AS $$
BEGIN
--     PREPARE addProject (VARCHAR(45),SMALLINT) AS
--     INSERT INTO projects (projectName, year) VALUES ($1, $2);
--     EXECUTE addProject(projectName, projectYear );

    EXECUTE 'INSERT INTO projects (projectName, year) VALUES ($1, $2)'
    USING projectName,projectYear;
END $$;

我正在尝试编写对SQL注入安全的存储过程。来自Mysql,我知道我必须使用带参数的预备语句。在Postgresql中,它不允许(注释的代码),另一方面,如果我使用动态命令,它会起作用。有人可以解释,为什么在这种情况下无法使用准备好的陈述?

1 个答案:

答案 0 :(得分:2)

已经为PL / PgSQL准备并缓存了执行计划,它会自动发生。因此,为了优化起见,无需在PL / PGSQL中使用PREPARE(如您所见,您不能)。

如果使用动态参数并使用串联将其附加而不是参数化,则可以进行

SQL注入。但是,由于您运行的是没有动态列/表的简单插入,因此不需要EXECUTE

CREATE OR REPLACE procedure CreateProject(
   IN projectName  VARCHAR(45),
   IN projectYear  SMALLINT  )
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO projects (projectName, year) VALUES ($1, $2);
END $$;

DEMO