2012-03-23 27 views
2

MySQLデータベースを使用しており、ストアドプロシージャを作成しようとしています。 query1の結果にレコードがない場合、別のクエリを実行するようにするにはどうすればよいですか?ここで条件が真である場合、MySQLストアドプロシージャでクエリを実行します。

は、私がこれまで持っているものです。

/* 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", ""); 

私は最初が行を持っていない場合にのみ、クエリを実行し、二次クエリを実行します。これを行う最善の方法は何ですか? SQL Serverでは

+0

テーブルと挿入文は動的でなければならないという要件がありますか?動的SQLを使用して良いアプローチではありません。 –

答えて

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> 

OKストアドプロシージャを3回呼び出しました。最初は何も得られません。 2番目の値は2番目の値を取得します。 3番目の値が最初の値になります。

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> 

試してみてください!

+0

素晴らしいおかげでRolando! ENGINE = MEMORYの場合。最後に手動で削除することを心配する必要がありますか?各実行後にデータがクリアされるのですか、それとも処理しなければなりませんか? – user391986

+0

DB接続が正常に切断されるか、予期せず終了するかにかかわらず、TEMPORARY TABLEは自動的にクリアされます。 – RolandoMySQLDBA

1

、あなたは一時テーブルに結果を実行し、このような行のために一時テーブルをチェックすることができます。mysqlで

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 
1

あなたは、このような手順で構築found_rows()を使用することができます。

[email protected]:~$ 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を使用できます。そして、あなたが最初の問合せが行を返さない場合にのみ、2番目のクエリを実行することができます:

EXECUTE QUERY; 

IF @@rowcount = 0 
BEGIN 
    PREPARE QUERY FROM @querytwo;  
    EXECUTE QUERY; 
END 
+0

エラー1193(HY000):システム変数 'rowcount'が不明です – user391986

+0

MySqlサーバには@@ rowcountがありません。ここで同等のものを見つけることができますhttp://stackoverflow.com/questions/2229218/what-is-mysql -version-of-rowcount – dmportella

+0

主なものはFound_Rows()です。このドキュメントはhttp://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_foundrowsにあります。 – dmportella

関連する問題