Как стать автором
Обновить

Комментарии 13

1. спасибо, опечатка вышла
2. спасибо! :)
Почитайте про вложенные множества (NESTED SETS), может тоже поможет решить вашу задачу.
для работы с хранимыми процедурами достаточно mysql 5.0

>Нельзя написать свою функцию, без использования сторонних сурсов?
можно
>И на сколько это может быть эффективней
Все зависит от специфики задачи, может быть значительно эффективнее :)

Небольшой пример:
-------------------------------------------
DELIMITER //

DROP PROCEDURE IF EXISTS `search`//
CREATE PROCEDURE `search`(IN firstname VARCHAR(255))
BEGIN
SET @firstname = firstname;
SET @outQuantity = 0;
SET @query = "SELECT SQL_CALC_FOUND_ROWS User.* FROM users User";
IF @firstname != '' THEN
SET @query = CONCAT(@query, "where User.first_name LIKE '", @firstname ,"%' ");
END IF;
PREPARE STMT FROM @query;
EXECUTE STMT;
SELECT FOUND_ROWS() INTO @outQuantity;
END
//
DELIMITER ;
-------------------------------------------
если Вы хотите потом использовать хранимые процедуры из php почитайте тут:
http://forums.mysql.com/read.php?52,73171,73171
там написано как делать запрос используя mysql экстеншен

если у вас mysqli см. mysqli_multi_query + mysqli_store_result
Что за кошмарный пример?
Переменные объявляются с помощью ключевого слова DECLARE с указанием типа, а не используются глобальные, это снижает скорость работы.
Динамические запросы не следует использовать, в данном случае можно просто IF в теле запроса использовать, что-то типа
SELECT SQL_CALC_FOUND_ROWS User.* FROM users User
WHERE IF(@firstname != '', User.first_name LIKE CONCAT(@firstname,'%'), 1);
пременные менять не стал.
Не покажете пример с использованием переборки, т.е. WHILE, FOR?

Вот то, что сейчас есть на PHP:

function returnLastId($into_id) {
    $r = DB::qArray("SELECT `cat_id` FROM `cat_categ` WHERE `cat_parent_id`=$into_id");
    foreach($r as $res) {
        $this->ids_arr[] = $res[0];
        self::returnLastId($res[0]);
    }
}
для перебора необходимо использовать курсор
DECLARE m_cat_id INT;
DECLARE done INT;
DECLARE cur1 CURSOR FOR
SELECT `cat_id` FROM `cat_categ` WHERE `cat_parent_id`=m_info_id
/* стейт сработает, когда из запроса нечего выбирать */
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

REPEAT
FETCH cur1 INTO m_cat_id;
IF NOT done THEN
/* здесь нужный код, здесь довольно все просто, как и в пхп */
END IF;
UNTIL done END REPEAT;

так как массивов нет, скорее всего нужно создавать временную табличку для накопления, как вариант, можно накидать в строку, если нужен список идентификаторов для IN, но тогда придется динамически формировать запрос, это плохо отражается на производительность, можно сразу обрабатывать данные. Если необходимо расчитанные данные, чтобы потом фетчем вытянуть, то только создание таблички, можно кончно возвращать с помощью SELECT на каждую итерацию, но будет слишком много результатов, что тоже плохо отразится на быстродействии.
Спасибо! Попробуй :)
давайте попробую дать непрошенный совет.
Если уж речь зашла о хранимых процедурах, то стоит задуматься о переходе на Postgres, который мало того, что имеет возможность работать с процедурами на нескольких языках, причем гораздо удобнее, чем мускул, так и гораздо лучше себя ведет при больших нагрузках.
всем спасибо за советы, очень помогли! всем в карму по плюсу :)
Может просто Stored Procedure, а не UDF, UDF давно уже есть, вроде с 3-й версии и пишутся он на C, глюков будет ну очень много.
Клёво. Теперь вы перенесёте "большие переборки" из php в mySQL и лишитесь тем самым возможности их адекватно отлаживать и вообще контролировать, как следствие у вас есть все возможности получить большую нагрузку если не сейчас то в будущем. Тут всё нужно делать крайне осторожно.
нет, ну я говорю о контрольных переборках, т.е. о тех которые уже были отлажены на 100%, что бы их можно было безбоязненно перенести в mysql. И снять лишние обработки с php. :) А так, ты конечно правы
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.