2013-05-24 1 views
1

я сделал этот код:PostqreSQL Повторяющиеся значения WHERE 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'])."' 
); 

Смысл этого кода должен быть, что он проверяет, является ли значение Allready существует в базе данных, и если он не делает, то он входит в нее. Это аддоны ($ _ POST ['authorlastname2']). «Представляет собой вход, но его можно легко заменить на«% myentereddata% »

Моя проблема в том, что он ничего не делает ... даже не дать сообщение об ошибке, его успех, но он не вводит данные, если данные не существуют в db allready и не уверены, что он прекратит ввод данных, если данные существуют.

Поэтому я был бы признателен, если бы кто-то помог мне решить проблему с этим кодом или дать другой пример, как это сделать по-другому, чтобы он работал.

Мой идентификатор первичный и последовательный, поэтому нет необходимости, чтобы вставить его

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

Запрос возвращается успешно: 1 ряд пострадавших, 60 мса время выполнения.

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 мс.

+0

ВЫ ХОТИТЕ получить сообщение об ошибке, если попытаетесь вставить строку, которая уже существует? Или вы хотите вставить его, если его нет, и спокойно игнорировать его, если он уже существует? –

ответ

1

Проблема заключается в том, что есть два из статей вместо одного. Вы фактически вставляете одну и ту же строку столько раз, сколько строк во всей таблице (когда выполняется условие 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, он по умолчанию включен.

Используйте вместо этого pg_escape_string.

+0

Да, это работает, спасибо. – mudsao

+0

@mudsao Пожалуйста, отметьте этот ответ как правильный (крючок под номерами слева) –

0

Если вы хотите просто убедиться, что в таблице нет дубликатов записей, вы должны использовать UNIQUE.

Таким образом, когда вы INSERT линии, которая уже есть, вы получите сообщение об ошибке.

Как это:

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

После этого вы не сможете INSERT тот же набор firstnames и lastnames дважды.

Вы тогда INSERT как это:

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

Это то, что я получил при использовании значений, которые was'nt в базе данных: Запрос успешно возвращен: 606208 затронутых строк, время выполнения 18829 мс. (didnt eneter ничего) И это то, что я получил с ним снова с теми же значениями: Запрос успешно возвращен: 1212416 затронутых строк, время выполнения 41933 мс. (все еще не сделана запись ...) Mayby его проблема с postgresql, используя PostgreSQL 9.1 – mudsao

+0

Вы совершили транзакцию? –

+0

@mudsao Было ли ваше намерение INSERT 600.000 новых линий? Или вы просто хотите вставить одну строку? –