PostgreSQL重复值不存在

时间:2013-05-24 12:19:05

标签: postgresql sql-insert not-exists

我制作了这段代码:

INSERT into author(authorfirstname1, authorlastname1,authorfirstname2, authorlastname2)
select '".addslashes($_POST['authorfirstname1'])."','".addslashes($_POST['authorlastname1'])."','".addslashes($_POST['authorfirstname2'])."','".addslashes($_POST['authorlastname2'])."'
from author
where not exists(select authorfirstname1, authorlastname1, authorfirstname2, authorlastname2 from author
where author.authorfirstname1='".addslashes($_POST['authorfirstname1'])."'
and author.authorlastname1='".addslashes($_POST['authorlastname1'])."'
and author.authorfirstname2='".addslashes($_POST['authorfirstname2'])."'
and author.authorlastname2='".addslashes($_POST['authorlastname2'])."'
);

这段代码的重点应该是它检查,如果数据库中已经存在一个值,如果它没有,那么它就进入它。 这个'.addslashes($ _ POST ['authorlastname2'])。“'代表一个输入,但很容易被'%myentereddata%'替换

我的问题是它没有做任何事情......甚至没有给出错误信息,它的成功,但如果数据不存在于db allready中并且不确定它是否在数据存在时停止输入数据,则它不会输入数据。

所以如果有人可以帮助我解决这段代码的问题,或者给出另一个例子如何以不同的方式做到这一点,我会感激不尽,这样才能有效。

我的ID是主要和序列号,因此无需插入

INSERT INTO author (authorfirstname1, authorlastname1,authorfirstname2, authorlastname2)
VALUES ('one','two','three','four');

查询成功返回:1行受影响,60 ms执行时间。

INSERT into author(authorfirstname1, authorlastname1,authorfirstname2, authorlastname2)
select 'one','two','three','four'
from author
where not exists(select authorfirstname1, authorlastname1, authorfirstname2, authorlastname2 from author
where author.authorfirstname1='one'
and author.authorlastname1='two'
and author.authorfirstname2='three'
and author.authorlastname2='four'
);

查询成功返回:受影响的行数为657,执行时间为40毫秒。

INSERT into author(authorfirstname1, authorlastname1,authorfirstname2, authorlastname2)
select 'new','new','new','new'
from author
where not exists(select authorfirstname1, authorlastname1, authorfirstname2, authorlastname2 from author
where author.authorfirstname1='new'
and author.authorlastname1='new'
and author.authorfirstname2='new'
and author.authorlastname2='new'
);

查询成功返回:受影响的行数为1314行,执行时间为70毫秒。

2 个答案:

答案 0 :(得分:1)

问题是有两个FROM子句而不是一个。实际上,插入同一行的次数与整个表中的行数一样多(当满足WHERE子句时)。 查询应该是(请注意,与您的版本相比,第一个FROM已被删除):

INSERT into author(authorfirstname1, authorlastname1,authorfirstname2, authorlastname2)
select 'one','two','three','four'
where not exists(select 1 from author
where author.authorfirstname1='one'
and author.authorlastname1='two'
and author.authorfirstname2='three'
and author.authorlastname2='four'
);

内部选择中的列也已被删除。 SELECT 1 FROM...足以检查是否存在行,不需要提取特定列,无论如何它们都将被丢弃。

另一个不相关的问题是,只要任何注入的参数包含引号字符,使用addslashes进行的转义就会产生无效的查询。

这是因为当PG的standard_conforming_strings设置为ON时,反斜杠是一个普通字符,不会转义任何内容。从PostgreSQL 9.1开始,它默认为ON。

改为使用pg_escape_string

答案 1 :(得分:0)

如果您只是想确保表格中没有重复的条目,您应该使用UNIQUE

这样,无论何时INSERT已经存在的行,都会出现错误。

像这样:

CREATE UNIQUE INDEX ON author (authorfirstname1, authorlastname1, authorfirstname2, authorlastname2);

之后,您将无法INSERT两次使用相同的名字和姓氏。

然后你INSERT这样:

INSERT into author(authorfirstname1, authorlastname1,authorfirstname2, authorlastname2)
VALUES ('".addslashes($_POST['authorfirstname1'])."', '".addslashes($_POST['authorlastname1'])."', '".addslashes($_POST['authorfirstname2'])."', '".addslashes($_POST['authorlastname2'])."')