Скажите а "select * from Products where product_id=$p_id and region=$key" Может вернуть больше одной записи за один проход?
Не пойму просто логическую суть условия if ($smth->num_rows!=0)
если задача найти именно дублирующиеся записи то по идеи должно быть if ($smth->num_rows>1) т.к. 1 строка это не дубликат. Получается что в Select как таковом отпадает всякая нужна просто update и всё (есть что обновить обновит нету нет) и если в самой таблице настроить уникальность по двум полям то можно следом и insert делать, он все равно не задвоит данные.
по вашему примеру получается что update можно делать и если больше одной записи в базе соответсвует выборке ваше условие !=0 предполагает что нужно обновить все записи которые соответсвуют выборке сколько бы их в базе не было
Есть ещё такая штука как replace, работает также как инсерт если в базе найдется запись которая совпадет по значению первичных ключей (если product_id и region у вас являются таковыми) со вставляемой строкой то произойдет Update
Опять возвращаемся к тому что сложно посоветовать что то конкретное не видя структуру таблицы её ключей и индексов
Вполне вероятно что в вашем случае просто вместо конструкций из if можно написать:
$sql = "REPLACE INTO Products (product_id, region, prices_purchase, prices_selling, prices_discount)
VALUES ('$p_id', '$key', '$p_purchase', '$p_selling', '$p_discount')";
p.s.
то что пишу ниже это офтоп но не совсем, вы спрашивали "Можете посоветовать что можно изменить в коде"
Могу.
Строить запросы так как это делаете Вы неправильно с точки зрения безопасности, правильно было бы сделать так:
для INSERT
$sql = "INSERT INTO Products
SET
product_id= :product_id,
region= :region,
prices_purchase= :prices_purchase,
prices_selling= :prices_selling,
prices_discount= :prices_discount
";
// подготовка запроса
$stmt = $this->bd_connect->prepare($sql);
// привязываем значения
$stmt->bindParam(':product_id',$p_id);
$stmt->bindParam(':region',$key);
$stmt->bindParam(':prices_purchase',$p_purchase);
$stmt->bindParam(':prices_selling',$p_selling);
$stmt->bindParam(':prices_discount',$p_discount);
//Выполняем запрос
$stmt->execute()
Для SELECT
$sql = "SELECT * FROM Products
WHERE product_id= :p_id AND region= :key";
// подготовка запроса
$stmt = $this->bd_connect->prepare($sql);
// привязываем значения
$stmt->bindParam(':p_id',$p_id);
$stmt->bindParam(':key',$key);
// выполняем запрос
$stmt->execute();
// получаем количество строк
$num = $stmt->rowCount();
// одним из распространенных вариантов получаем значения (смотри php PDO)
$row = $stmt->fetch(PDO::FETCH_ASSOC);
Перед привязкой значений можно а часто даже нужно дополнительно обработать ( слеши там всякие и т.п. :) ), то, что собираешься биндить