如果条件为真,则在MySQL存储过程中运行查询

时间:2012-03-23 19:12:15

标签: mysql sql database

我正在使用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 个答案:

答案 0 :(得分:3)

这需要一些工作,但我做了足够的调整。您的代码问题与您的逻辑无关,但与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 :(得分:1)

在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

答案 2 :(得分:1)

在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

答案 3 :(得分:0)

我最简单的工作代码

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