Mysql ストアドファンクション 意図しない結果

このQ&Aのポイント
  • ストアドファンクションを作成したが、引数に関係なく戻り値が常に全ての行になってしまう
  • ストアドファンクションのWhere句が正しく機能していない原因を教えて欲しい
  • fgetLineNew関数を実行しても、戻り値が常に817の値になる
回答を見る
  • ベストアンサー

Mysql ストアドファンクション 意図しない結果

以下の通りストアドファンクションを作成しました。 関数名:fgetLineNew インパラメータ:shop Varchar 8 ※1つだけ。。。 戻り値: Int 11 <ソース> BEGIN DECLARE pline INTEGER(11) DEFAULT NULL; SELECT COUNT(1) INTO pline FROM `hoge` WHERE `SHOP` = shop; IF pline IS NULL THEN SET pline = 10000; END IF; RETURN pline; END 上記のように、作成したストアドファンクションですが、 どんな引数を入れても、戻り値が全ての行(817行)になってしまいます。 以下を参照。 Where区がまったく働いていないのですが、何が原因なのでしょうか。 教えてください。 <ストアドファンクション実行> mysql> select fgetLineNew(1); +----------------+ | fgetLineNew(1) | +----------------+ | 817 | +----------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(101); +------------------+ | fgetLineNew(101) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew('525'); +--------------------+ | fgetLineNew('525') | +--------------------+ | 817 | +--------------------+ 1 row in set (0.01 sec)

  • MySQL
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.1

WHERE `SHOP` = shop; shopはテーブルのカラム名になります。 パラメータにする場合は WHERE `SHOP` = :shop; としましょう。

Kamen_Ride
質問者

お礼

引数のshop を、shop_in にかえたところうまくいきました。 ありがとうございました。

関連するQ&A

  • ストアドファンクション⇒プロシージャ呼出し失敗する

    参考の通りに、ストアドプロシージャ作成SQL文を発行し、 コマンドライン上からは、以下の通りの結果1となり、 レコードがinsertされます。 <結果1> mysql> call logger('ほげ', 'ホゲ'); Query OK, 1 row affected (0.01 sec) mysql> select * from PROCEDURE_LOG; +--------+--------+---------------------+ | NAME | QUERY | EXECUTE_DATE | +--------+--------+---------------------+ | ほげ | ホゲ | 2014-03-26 10:41:26 | +--------+--------+---------------------+ 1 row in set (0.00 sec) ですが、testというストアドファンクションから呼び出してみましたが、 以下の結果2の通り、失敗します。 <結果2> mysql> select test(); ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger <test> BEGIN CALL logger('test','1'); RETURN CONCAT('END'); END 現在動作している環境では、どこでエラーが発生したかがわからず、 ロガーの処理をなんとしても実装したいのですが、 いろいろ試してみても、解決できませんでした。 ご教示のほど、よろしくお願いします。 <参考> http://treeapps.hatenablog.com/entry/20120106/p1 <ストアドプロシージャ作成SQL文(logger)> SET NAMES UTF8; delimiter // -- ログ出力 DROP PROCEDURE IF EXISTS logger// CREATE PROCEDURE logger( IN PROCEDURE_NAME TEXT, IN SQL_TEXT TEXT ) BEGIN DECLARE CNT INT; CREATE TABLE IF NOT EXISTS PROCEDURE_LOG ( NAME VARCHAR(64), QUERY TEXT, EXECUTE_DATE TIMESTAMP, KEY IDX1 (NAME, QUERY(64), EXECUTE_DATE) ) ENGINE=MYISAM DEFAULT CHARSET=UTF8; -- 古いログを削除 SELECT COUNT(*) INTO CNT FROM PROCEDURE_LOG; IF CNT >= 1000 THEN DELETE FROM PROCEDURE_LOG LIMIT 1; END IF; -- テーブルにログを記録 SET @sql = CONCAT('INSERT INTO PROCEDURE_LOG VALUES (', QUOTE(PROCEDURE_NAME), ',', QUOTE(SQL_TEXT), ', null)'); PREPARE stmt FROM @sql; EXECUTE stmt; END // delimiter ;

    • ベストアンサー
    • MySQL
  • MYSQL ストアドプロシージャの記述方法

    MYSQLのストアドプロシージャについて分からないことがあり質問させて頂きます。 SQLのwhere句の部分を引数によって条件分で変更させたいと考えています。そこでORACLEの場合は変数にいれて最後に明示的にSQLを発行して いたので可能だったのですが、MYSQLの場合はどういった記述になる のかわかりません。やりたいことは下記のような感じです。 ORACLEの場合は procedure prctest(pc out refcur,a in varchar2,b in varchar2) is sqldata varchar2(1000); whereinfo varchar2(1000); begin sqldata := 'select ID , NAME from testTbl '; if (a IS NOT NULL) then   whereinfo := whereinfo || ' acol = a ' ; end if; if (b IS NOT NULL) then   if (whereinfo IS NOT NULL) then  whereinfo := whereinfo || ' and ';   end if;   whereinfo := whereinfo || ' acol = b ' ; end if; if (whereinfo IS NOT NULL) then  sqldata := sqldata || ' where ' || whereinfo ; end if; open pc for sqldata; (ここでSQLが入ったSQLを発行) end prctest; (抜粋) ストアドをあまり使用したことがなく良い説明ではないかも しれませんが、アドバイスの方頂けたらと思います。 よろしくお願いします。

  • ストアドファンクションがうまく作成できない

    SQL Server 2005 にて、 以下のようなストアドファンクションを作成しようとしても、 「メッセージ 156、レベル 15、状態 1、プロシージャ TestKansu、行 30 キーワード 'end' 付近に不適切な構文があります。」 といったエラーメッセージが表示されてしまい、 うまく作成できません。。 文法など、いろいろ調べてみたところ、特に問題なさそうな 感じではあるのですが。。 どこに問題があるのか、どなたかご教授願えないでしょうか? なにとぞ、よろしくお願いいたします。 -------------------------------- use tempdb go -- 呼び出し形式 create function TestKansu ( @Date as datetime, @Type as varchar(1) ) returns @ReturnTable table ( StartDate varchar(8), EndDate varchar(8) ) as begin if @Type is null begin raiserror('正しいtypeを指定してください',-1,-1) end if @Date is null begin SET @Date = getdate() end if @Type = '0' begin insert into @ReturnTable select convert(varchar(8), dateadd(dd ,-2 ,@Date), 112) as StartDate, convert(varchar(8), dateadd(dd ,-2 ,@Date), 112) as EndDate, end if @Type = '1' begin insert into @ReturnTable select convert(varchar(8), @Date, 112) as StartDate, convert(varchar(8), @Date, 112) as EndDate end return end --------------------------------

  • MySQL 5.1 のCHAR(M)型に関して

    MySQL 5.1の CHAR(M)型のMは「文字数」でしょうか?それとも「バイト数」でしょうか? 教えて頂けませんか? 自分の認識では「文字数」と思っているのですが、下記のような現象が発生しております。 mysql> mysql> mysql> mysql> mysql> SHOW CREATE TABLE TEST\G; *************************** 1. row *************************** Table: TEST Create Table: CREATE TABLE `TEST` ( `MOJI` char(6) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.01 sec) ERROR: No query specified mysql> mysql> SELECT * FROM TEST; Empty set (0.00 sec) mysql> mysql> INSERT INTO TEST (MOJI) VALUES ('ああああ'); Query OK, 1 row affected, 1 warning (0.00 sec) mysql> mysql> SELECT * FROM TEST; +--------+ | MOJI | +--------+ | ああ | +--------+ 1 row in set (0.00 sec) mysql> mysql> INSERT INTO TEST (MOJI) VALUES ('abcdef'); Query OK, 1 row affected (0.00 sec) mysql> mysql> SELECT * FROM TEST; +--------+ | MOJI | +--------+ | ああ | | abcdef | +--------+ 2 rows in set (0.00 sec) mysql> mysql> mysql> mysql> 環境はCentOS 5.5 で、OSの文字コードもMySQLの文字コードも「utf8」としています。 どうかご教授下さい。

  • mysqlコマンドとPHPで同じSQLの結果が違う

    MySQL 5.5で、mysqlコマンドからSQLを流したときと、PHPから同じSQLを発行したときで結果が違うのです。 どうも日付のパースが関係しているようで、「2014-08-19」と書くとどちらも同じ結果になるのに、 「2014-8-19」と書くとPHPでは1行も返ってこなくなります。 再現例: ================== CREATE TABLE t (day date NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; INSERT INTO t (day) VALUES ('2014-08-19'); SELECT * FROM t WHERE day = '2014-8-19'; +------------+ | day | +------------+ | 2014-08-19 | +------------+ 1 row in set (0.00 sec) ↑同じSELECTをPHPから発行すると1行も返ってこない。 ================== mysqldとmysqlは5.5.30。 phpinfo()のmysqlのセクションでは Client API version 5.5.30 と出ています。 show variablesで見るとdate_formatはどちらも%Y-%m-%dになっています。 他にどこを確認すればいいでしょうか?

  • MySQLのサブクエリーでエラーがでます

    現在MySQLを使って開発をしています。 SQLもMySQLもまだあまり使ったことがないのでなにか大きな勘違いをしている かもしれませんが、自分で作ったデータベースにMysqlコマンドでアクセスし、 以下のようにselectを行うとsyntaxエラーが発生します。 mysql> select CREATE_DATE from user where cust_id = (select cust_id from customer where memo = 'memo'); ERROR 1064: You have an error in your SQL syntax near 'select cust_id from customer where memo = 'memo')' at line 1 しかしサブクエリーの内容も、その前のselectもそれぞれ下記のように単体で実行すると正常に動作するので、文法的には間違っていないと思います。 ERROR 1064のsyntaxエラーは何を指しているのでしょうか? ぜひご教示ください。 mysql> select cust_id from customer where memo = 'memo'; +---------+ | cust_id | +---------+ | 1 | +---------+ 1 row in set (0.00 sec) mysql> select CREATE_DATE from user where cust_id = '1'; +-------------+ | CREATE_DATE | +-------------+ | 2001-07-23 | +-------------+ 1 row in set (0.00 sec)

  • MySQLのストアドプロシージャについて

    MySQL5.6のストアドプロシージャが返すSELECT結果のフェッチ方法について教えてください。 delimiter $ create procedure sample_proc() begin select * from TEST_TBL; end$ の様なストアドプロシージャがあり、これを他のストアドプロシージャから呼び出して、 ループしながらフェッチしたいのですが、どうすればよいでしょうか。

  • MySQL5.0のストアドプロシージャで引数の使い方がわからなくて困っています。

    MySQL5.0のストアドプロシージャで引数の使い方がわからなくて困っています。 ストアドプロシージャで IF文で引数の空の判定と、 LIKE '%name%'にその引数を使いたいのです。 どなたかわかるかたいらっしゃいませんか? □プログラムからコールする strSQL = "CALL buttonaction_proc2(syohinCd, syohinCdLast, name, count) "; □ストアドプロージャ delimiter // CREATE PROCEDURE buttonaction_proc2(IN syohinCd INT(8), IN syohinCdLast INT(8), IN name VARCHAR(40), IN count INT(8)) IF ((syihinCd IS NOT NULL) OR (syohinCdLast IS NOT NULL) OR (name IS NOT NULL)) THEN AND (SYOHIN_CD BETWEEN syohinCd AND syohinCdLast) ELSE (IF syohinCd IS NOT NULL) THEN AND (SYOHIN_CD BETWEEN syohinCd AND count) ELSE IF (syohinCdLast IS NOT NULL) THEN ( AND (SYOHIN_CD BETWEEN 1 AND syohinCdLast) ) IF (name IS NOT NULL) THEN AND NAME LIKE '%name%' END IF END IF ORDER BY SYOHIN_CD; END //

  • ストアドファンクションのエラーについて

    PostgreSQLでストアドファンクションを作成しました。 ファンクションの内容は下記の通りです。 CREATE FUNCTION getRenban (VARCHAR) RETURNS VARCHAR(7) AS ' DECLARE key ALIAS FOR $1; code VARCHAR(7); code2 VARCHAR(2); code5 VARCHAR(5); renban INTEGER; new_code VARCHAR(7); BEGIN SELECT MAX(code) INTO code FROM M_ITEM WHERE flg = TRIM($1); code2 := TRIM($1); IF code IS NULL THEN renban := 1; ELSE SELECT SUBSTR(code, 2) INTO code5; SELECT TO_NUMBER(code5, ''99999'') INTO renban; renban := renban + 1; END IF; code5 := ''''; SELECT TO_CHAR(renban, ''00000'') INTO code5; SELECT code2 || code5 INTO new_code; RETURN new_code; END; ' language 'plpgsql' ; コンソール上で下記のコマンドを実行したらエラーが出力されました。 SELECT getrenban('01'); 出力されたエラーの内容は下記の通りです。 ERROR: value too long for type character varying(5) CONTEXT: PL/pgSQL function "getrenban" line 19 at SQL statement お恥ずかしいですがいくらコードを見てもどこが原因なのかわかりません。 申し訳ありませんがご教授お願いできませんでしょうか。 昨日から悩んでいます。 どうか助けて下さい、宜しくお願いします。

  • mySQLで結果が無いときの処理

    $sql = "select * from test "; $sql .= "where id='".$_POST["id"]."' and pwd='".$_POST["pwd"]."'"; $result = mysql_query($sql); while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { if($row){ $msg = "OK"; } } としていますが、NGのときってどういう風にしたらいいのでしょうか? 基本的なことですみませんが、教えてください。

    • ベストアンサー
    • PHP