C# アプリで MySQL のストアド プロシージャを作成しています。ストアド プロシージャには、動的に作成された SQL が含まれており、インデックスが存在する場合はそれを削除し、[再]作成するために使用されます。SQL コードは MySQL Workbench では正常に動作しますが、C# アプリから実行すると MySQL 例外が発生します。
ストアド プロシージャ コードは次のとおりです (C# で使用されるため、識別子の前に "@" 記号はありません。私が理解しているように、C# 自体がそれらを配置するためです)。
CREATE PROCEDURE recreate_index_sp(IN theTable varchar(128), IN theIndexName varchar(128), IN theIndexColumns varchar(128))
BEGIN
IF ((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name = theTable AND index_name = theIndexName) > 0) THEN
SET s = CONCAT( 'DROP INDEX ', theIndexName, ' ON ', theTable );
PREPARE stmt FROM s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
SET s = CONCAT('CREATE INDEX ' , theIndexName , ' ON ' , theTable, '(', theIndexColumns, ')');
PREPARE stmt FROM s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
私が得ている例外は次のとおりMySql.Data.MySqlClient.MySqlException: Unknown system variable 's'
です。
したがってs
、ストアド プロシージャの開始時に定義すると、DECLARE s varchar(255)
代わりにエラーが発生しますYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's;EXECUTE stmt;DEALLOCATE PREPARE stmt;END' at line 1
。しかし、MySQL Workbench で使用するコードは変数を定義する必要がないため、ここでそれを主張する理由がわかりません。
代わりに変数名として使用@s
すると (定義を含む!)、例外はParameter '@s' must be defined
.
これを機能させる方法はありますか?
情報として、私が MySQL Workbench で使用しているコードを以下に示します。
CREATE PROCEDURE recreate_index_sp(IN theTable varchar(128), IN theIndexName varchar(128), IN theIndexColumns varchar(128))
BEGIN
IF ((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name = @theTable AND index_name = @theIndexName) > 0) THEN
SET @s = CONCAT( 'DROP INDEX ', @theIndexName, ' ON ', @theTable );
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
SET @s = CONCAT('CREATE INDEX ', @theIndexName, ' ON ', @theTable, '(', @theIndexColumns, ')');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
EDIT:Reubzのおかげで、コードが機能しました。2 つの部分が必要でした: (1) 必要な接続文字列は「Allow User Variables=True;」です。(2) @ 記号が必要でした (変数は宣言する必要がありませんでした)。
だからここに作業コードがあります:
CREATE PROCEDURE recreate_index_sp(IN theTable varchar(128), IN theIndexName varchar(128), IN theIndexColumns varchar(128))
BEGIN
IF ((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name = theTable AND index_name = theIndexName) > 0) THEN
SET @sqlPrep = CONCAT( 'DROP INDEX ', theIndexName, ' ON ', theTable );
PREPARE stmt FROM @sqlPrep;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
SET @sqlPrep = CONCAT('CREATE INDEX ' , theIndexName , ' ON ' , theTable, '(', theIndexColumns, ')');
PREPARE stmt FROM @sqlPrep;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;