MySQL, процедура хранения, как получить результат от обоих запросов, обновление решить
Моя процедура: (это схема)
delimiter //
CREATE PROCEDURE get_random_data()
BEGIN
Declare Count_a INT;
SELECT Floor(Count(`id_x`) * Rand()) INTO Count_a From `x_data` Where `ok_w` = 1 And `active` = 2 And `time` >= Unix_timestamp();
# Now We select Some Rows
SELECT `id_x` From `x_data` Where `spec` = 1 Limit Count_a,3;
# And if Count of this select is small than < 3
IF(row_count() < 3) then
SELECT `id_anonsu` From `x_data` Where `spec` = 0 Limit Count_a,2;
END IF ;
END//
delimiter ;
// Цель
Как получить результаты от ОБА запросов? // Один из запроса перед оператором if
// Второй из запроса в операторе, если число первых запросов меньше 3
2 ответа
Решение
Хорошо, я нашел ответ.
Оригинальный код:
IF(row_count() < 3) then
SELECT `id_anonsu` From `x_data` Where `spec` = 0 Limit Count_a,2;
END IF ;
Был заменен на:
IF(FOUND_ROWS() < 3) THEN SELECT `id_anonsu` From `x_data` Where `spec` = 0 Limit Count_a,2;
END IF ;
Лучшая версия:
Хорошая работа с запросом (кто использует LIMIT) И нам нужно знать количество возвращаемых строк по (Query) в процедуре хранения
Версия с количеством выставок
DROP PROCEDURE IF EXISTS test;
Delimiter //
CREATE PROCEDURE test(OUT w INT)
BEGIN
Declare Counter_a INT DEFAULT 0;
Set @id_counter = 0;
SELECT Floor(Count(`id_x`) * Rand()) INTO Counter_a From `x_data` Where `ok_w` = 1 And `active` = 2 And `time` >= Unix_timestamp();
SELECT @id_counter := @id_counter + 1, `id_x` From `x_data` Where `spec` = 1 Limit Counter_a,3;
IF @id_counter < 3 THEN
Set Counter_a = Counter_a + 1;
SELECT `id_x` From `x_data` Limit Counter_a,2;
END IF;
Set w = @id_counter;
END //
Delimiter ;
Вывод как это:
mysql> Call test(@z); Select @z;
+--------------------------------+-----------+
| @id_counter := @id_counter + 1 | id_x |
+--------------------------------+-----------+
| 1 | 7 |
| 2 | 8 |
+--------------------------------+-----------+
2 rows in set (0.00 sec)
+-----------+
| id_x |
+-----------+
| 8 |
+-----------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
+------+
| @z |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
Версия со скрытым счетом
DROP PROCEDURE IF EXISTS test;
Delimiter //
CREATE PROCEDURE test(OUT w INT)
BEGIN
Declare Counter_a INT DEFAULT 0;
Set @id_counter = 0;
SELECT Floor(Count(`id_x`) * Rand()) INTO Counter_a From `x_data` Where `ok_w` = 1 And `active` = 2 And `time` >= Unix_timestamp();
SELECT `id_x` From `x_data` Where @id_counter := @id_counter + 1 And `spec` = 1 Limit Counter_a,3;
IF @id_counter < 3 THEN
Set Counter_a = Counter_a + 1;
SELECT `id_x` From `x_data` Limit Counter_a,2;
END IF;
Set w = @id_counter;
END //
Delimiter ;
Вывод как это:
mysql> Call test(@z); Select @z;
+-----------+
| id_x |
+-----------+
| 7 |
| 8 |
+-----------+
2 rows in set (0.00 sec)
+-----------+
| id_x |
+-----------+
| 8 |
+-----------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
+------+
| @z |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
@СОВЕТ
@id_counter := @id_counter + 1
Это должно быть раньше всех условий, в которых.
Например:
[.....] Where @id_counter := @id_counter + 1 And `field_2` > 1 LIMIT 0, 5;
Вернется всегда 1...
Правильная версия
[.....] Where `field_2` > 1 And [Other conditions] And @id_counter := @id_counter + 1 LIMIT 0, 5;
Это зависит от используемого вами клиентского интерфейса. JDBC, например, имеет Statement.getMoreResults()
Забавно, что запрос содержит разделитель // и // комментарии одновременно.