Запустите запрос в хранимой процедуре MySQL, если условие истинно - PullRequest
2 голосов
/ 23 марта 2012

Я использую базу данных MySQL и пытаюсь создать хранимую процедуру.Как сделать так, чтобы, если в результате запроса query1 не было записей, он выполнял другой запрос?

Вот что у меня есть:

/* CREATE DB */
CREATE DATABASE mydata;
use mydata;
/* TABLE */
CREATE TABLE mydata (
ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name                        VARCHAR(255) NOT NULL,
Value                       VARCHAR(255) NOT NULL
) ENGINE=InnoDB;
INSERT INTO mydata (Name, Value) VALUES ("testname", "testvalue");

/* STORED PROCEDURE */
delimiter //
CREATE PROCEDURE myproc(IN myTable VARCHAR(255), 
                        IN myValue VARCHAR(255), 
                        IN myValueTwo VARCHAR(255))
BEGIN
    SET @iTable=myTable;
    SET @iValue=myValue;
    SET @iValueTwo=myValueTwo;

    SET @query = CONCAT('SELECT Name FROM ', @iTable, 
        ' WHERE Value="', @iValue, '"');
    SET @querytwo = CONCAT('SELECT Name FROM ', @iTable, 
        ' WHERE Value="', @iValueTwo, '"');
    PREPARE QUERY FROM @query;
    EXECUTE QUERY;

END //
delimiter ;

/* CALL */
call myproc("mydata", "testvalue", "");

Я хочу запуститьзапрос, и выполнить вторичный запрос, только если первый не имеет строк.Каков наилучший способ сделать это?

Ответы [ 4 ]

3 голосов
/ 24 марта 2012

Это заняло некоторую работу, но я внес достаточно корректив. Проблема с вашим кодом не имеет ничего общего с вашей логикой, а с самим языком хранимых процедур MySQL. При выполнении динамического SQL возникают проблемы с областями видимости.

Я создал временную таблицу и поместил в нее возвращенное значение

Вот некоторые загруженные образцы данных

mysql> drop database if exists user391986;
Query OK, 1 row affected (0.08 sec)

mysql> create database user391986;
Query OK, 1 row affected (0.00 sec)

mysql> use user391986
Database changed
mysql> CREATE TABLE mytable (
    -> ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> Name VARCHAR(255) NOT NULL,
    -> Value VARCHAR(255) NOT NULL
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.11 sec)

mysql> INSERT INTO mytable (Name,Value) VALUES
    -> ('rolando','edge'),('pamela','washington'),
    -> ('dominique','wilkins'),('diamond','cutter');
Query OK, 4 rows affected (0.06 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> SELECT * from mytable;
+----+-----------+------------+
| ID | Name      | Value      |
+----+-----------+------------+
|  1 | rolando   | edge       |
|  2 | pamela    | washington |
|  3 | dominique | wilkins    |
|  4 | diamond   | cutter     |
+----+-----------+------------+
4 rows in set (0.00 sec)

mysql>

Вот хранимая процедура, настроенная для захвата возвращаемых значений во временной таблице

mysql> delimiter //
mysql> CREATE PROCEDURE myproc(IN myTable VARCHAR(255), IN myValue VARCHAR(255), IN myValueTwo VARCHAR(255))
    -> BEGIN
    ->     DECLARE foundcount INT;
    ->     DECLARE retval VARCHAR(255);
    ->
    ->     SET @iTable=myTable;
    ->     SET @iValue=myValue;
    ->     SET @iValueTwo=myValueTwo;
    ->
    ->     CREATE TEMPORARY TABLE IF NOT EXISTS mynumber (rv VARCHAR(255)) ENGINE=MEMORY;
    ->     DELETE FROM mynumber;
    ->
    ->     SET retval = 'nothing retrieved';
    ->     SET @query = CONCAT('INSERT INTO mynumber SELECT Name FROM ', @iTable, ' WHERE Value=''', @iValue, '''');
    ->     PREPARE QUERY FROM @query;
    ->     EXECUTE QUERY;
    ->     DEALLOCATE PREPARE QUERY;
    ->     SELECT COUNT(1) INTO foundcount FROM mynumber;
    ->     IF foundcount = 0 THEN
    ->         SET @querytwo = CONCAT('INSERT INTO mynumber SELECT Name FROM ', @iTable, ' WHERE Value=''', @iValueTwo, '''');
    ->         PREPARE QUERY FROM @querytwo;
    ->         EXECUTE QUERY;
    ->         DEALLOCATE PREPARE QUERY;
    ->     END IF;
    ->     SELECT COUNT(1) INTO foundcount FROM mynumber;
    ->     IF foundcount > 0 THEN
    ->         SELECT rv INTO retval FROM mynumber;
    ->     END IF;
    ->     SELECT retval;
    ->
    -> END //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql>

ОК. Я вызвал хранимую процедуру три раза. Первый ничего не получает. Второе получает второе значение. Третье получает первое значение.

mysql> CALL myproc('mytable','pamela','diamond');
+-------------------+
| retval            |
+-------------------+
| nothing retrieved |
+-------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.02 sec)

mysql> CALL myproc('mytable','pamela','wilkins');
+-----------+
| retval    |
+-----------+
| dominique |
+-----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

mysql> CALL myproc('mytable','edge','wilkins');
+---------+
| retval  |
+---------+
| rolando |
+---------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.02 sec)

mysql>

Попробуй !!!

1 голос
/ 24 марта 2012

В mysql вы можете использовать встроенную процедуру found_rows(), например:

el@apollo:~$ mysql -u root -p
Enter password: 
mysql> use your_database;
Database changed
mysql> select id from problems;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
+----+
4 rows in set (0.00 sec)

mysql> select found_rows();
+--------------+
| found_rows() |
+--------------+
|            4 |
+--------------+
1 row in set (0.00 sec)

В mssql вы можете использовать значение @@rowcount.Тогда вы можете запустить второй запрос, только если первый запрос не дал никаких строк:

EXECUTE QUERY;

IF @@rowcount = 0
BEGIN
     PREPARE QUERY FROM @querytwo;     
     EXECUTE QUERY;
END
1 голос
/ 23 марта 2012

В Sql Server вы можете запустить результаты во временную таблицу, а затем проверить временную таблицу на наличие строк, подобных этой:

declare @numberResults int = 0

create table #MyTempTable(...)

insert #MyTempTable
sp_executesql Query

set @numberResults = (select count(*) from #MyTempTable)

if @numberResults = 0
 begin
  sp_executesql secondQuery
 end
0 голосов
/ 15 октября 2018

Мой самый простой рабочий код

BEGIN
    IF test = 'null' THEN 
        PREPARE QUERY FROM 'SELECT username as name from login';
        EXECUTE QUERY;
    ELSE
        PREPARE QUERY FROM 'SELECT username as name2 from login';
        EXECUTE QUERY;
    END IF;
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...