如何在 DO 语句中使用准备好的语句?
How to use prepared statements in DO statements?
我有一个相当复杂的查询,我试图使用准备好的语句来保护我的数据库免受 SQL 注入。我基本上将多个查询链接在一个 begin-end 块下。
此复合查询首先检查用户会话是否存在,然后检查用户是否已被禁止,然后检查用户输入的标签是否有效,最后将 post 插入数据库。
这里是查询:
query = "DO
$$
BEGIN
IF
(select exists(select user_id from sessions where unqid = and user_id = ))
THEN
IF
(select banned_till from users where unqid = ) > now()
THEN
RAISE EXCEPTION 'User has been banned!';
ELSE
IF (
Select ( SELECT array_agg(DISTINCT name) FROM allowed_tags) @> )
THEN
insert into posts (unqid, title, link, content, user_id, user_nick, user_flair,
tags, tags_details, likes, likes_details)
SELECT , , , ,
, user_nick, user_flair,
, , 1,
from users where unqid = ;
ELSE
RAISE EXCEPTION 'Fake tags detected!';
END IF;
END IF;
ELSE
RAISE EXCEPTION 'User is not logged in';
END IF;
END
$$;"
DB.exec query,
session_id, session_user, tags_list, unqid, title, link, content,
tags_obj.to_json, tags_details_obj.to_json, likes_obj.to_json
当我使用字符串插值时,这个查询工作正常。但是当我尝试使用准备好的语句时,我开始得到;
bind message supplies 10 parameters, but prepared statement "" requires 0
如何在查询中使用准备好的语句?
您不能将 DO
语句用作准备好的语句。
我建议您使用两个语句:
一个得到你需要判断是否有错误条件的三个结果
one to 运行 INSERT
语句
第二个是常规准备语句。
在我看来,您混淆了 PL/pgSQL 中的交易和 BEGIN ... END
区块。
我有一个相当复杂的查询,我试图使用准备好的语句来保护我的数据库免受 SQL 注入。我基本上将多个查询链接在一个 begin-end 块下。
此复合查询首先检查用户会话是否存在,然后检查用户是否已被禁止,然后检查用户输入的标签是否有效,最后将 post 插入数据库。
这里是查询:
query = "DO
$$
BEGIN
IF
(select exists(select user_id from sessions where unqid = and user_id = ))
THEN
IF
(select banned_till from users where unqid = ) > now()
THEN
RAISE EXCEPTION 'User has been banned!';
ELSE
IF (
Select ( SELECT array_agg(DISTINCT name) FROM allowed_tags) @> )
THEN
insert into posts (unqid, title, link, content, user_id, user_nick, user_flair,
tags, tags_details, likes, likes_details)
SELECT , , , ,
, user_nick, user_flair,
, , 1,
from users where unqid = ;
ELSE
RAISE EXCEPTION 'Fake tags detected!';
END IF;
END IF;
ELSE
RAISE EXCEPTION 'User is not logged in';
END IF;
END
$$;"
DB.exec query,
session_id, session_user, tags_list, unqid, title, link, content,
tags_obj.to_json, tags_details_obj.to_json, likes_obj.to_json
当我使用字符串插值时,这个查询工作正常。但是当我尝试使用准备好的语句时,我开始得到;
bind message supplies 10 parameters, but prepared statement "" requires 0
如何在查询中使用准备好的语句?
您不能将 DO
语句用作准备好的语句。
我建议您使用两个语句:
一个得到你需要判断是否有错误条件的三个结果
one to 运行
INSERT
语句
第二个是常规准备语句。
在我看来,您混淆了 PL/pgSQL 中的交易和 BEGIN ... END
区块。