6

テーブルから名前を取得するストアド プロシージャ関数を作成しました。問題は、テーブル名をパラメーターとして渡す必要があることです (この関数を使用する必要があるテーブルがいくつかあります)。

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `getName`(tableName VARCHAR(50), myId INT(11)) RETURNS VARCHAR(50)

  begin

  DECLARE myName VARCHAR(50);

  SELECT
    'name' INTO myName
  FROM
    tableName
  WHERE 
    id=myId;

  RETURN myName;

  end

このメソッドは、変数の実際の値の代わりに変数名 "tableName" を使用するため、エラーが発生します。

次のような手順を使用して、この問題を回避できます。CONCAT

    SET @GetName = CONCAT("
    SELECT
       'name'
    FROM
        ",tableName,"
    WHERE 
        id=",myId,";
    ");

    PREPARE stmt FROM @GetName;
    EXECUTE stmt;

...しかし、関数でこれを実行しようとすると、次のメッセージが表示されます。

動的 SQL は、ストアド関数またはトリガーでは許可されていません

代わりにプロシージャを使用しようとしましたが、関数のように単に値を返すようにすることはできませんでした。

それで、誰でもこの問題を回避する方法を見ることができますか?それは本当に信じられないほど基本的なようです。

4

1 に答える 1

16

識別子を使用して SQL ステートメントを作成する場合は、準備済みステートメントを使用する必要があります。ただし、準備済みステートメントは関数では使用できません。したがって、OUT パラメータを使用してストアド プロシージャを作成できます。

CREATE PROCEDURE getName
 (IN tableName VARCHAR(50), IN myId INT(11), OUT myName VARCHAR(50))
BEGIN

  SET @GetName =
    CONCAT('SELECT name INTO @var1 FROM ', tableName, ' WHERE id=', myId);
  PREPARE stmt FROM @GetName;
  EXECUTE stmt;

  SET myName = @var1;
END

使用例 -

SET @tableName = 'tbl';
SET @myId = 1005;
SET @name = NULL;
CALL getName(@tableName, @myId, @name);
SELECT @name;
于 2012-12-05T08:13:15.560 に答える