我尝试通过我的应用程序(C#winapp)执行此命令,但它显示错误,如参数' @sqlstmt'必须定义,但我尝试这个命令由navicat它运作良好,请帮助我
"DELIMITER $$" +
" DROP PROCEDURE IF EXISTS " + txtDB.Text + ".`index_startTime` $$" +
" CREATE PROCEDURE " + txtDB.Text + ".`index_startTime`" +
" (" +
" given_database VARCHAR(64)," +
" given_table VARCHAR(64)," +
" given_index VARCHAR(64)," +
" given_columns VARCHAR(64)" +
" )" +
" BEGIN" +
" DECLARE IndexIsThere INTEGER;" +
" SELECT COUNT(1) INTO IndexIsThere" +
" FROM INFORMATION_SCHEMA.STATISTICS" +
" WHERE table_schema = given_database" +
" AND table_name = given_table" +
" AND index_name = given_index;" +
" IF IndexIsThere = 0 THEN" +
" SET @sqlstmt = CONCAT('CREATE INDEX ',given_index,' ON '," +
" given_database,'.',given_table,' (',given_columns,')');" +
" PREPARE st FROM @sqlstmt;" +
" EXECUTE st;" +
" DEALLOCATE PREPARE st;"+
" ELSE" +
" SELECT CONCAT('Index ',given_index,' already exists on Table ',"+
" given_database,'.',given_table) CreateindexErrorMessage; "+
" END IF;"+
" END $$" +
" DELIMITER ;";
答案 0 :(得分:3)
该场景是需要调整mysql连接以允许用户变量支持的场景。如
string connString = @"server=localhost;userid=myUser;password=thePassword;database=stackoverflow;Allow User Variables=True";
(注意上面的结尾)。请参阅有关Allow User Variables=True
的MySQL手册页here。如果你不这样做,那么它会在用@
标志上用变量部分中的字符串输入。{/ p>
测试:
public void testCreateFunctionOnDB()
{ // http://stackoverflow.com/questions/40100348
using (MySqlConnection lconn = new MySqlConnection(connString))
{
lconn.Open();
MySqlCommand cmd = new MySqlCommand();
string sXX = @"DROP PROCEDURE IF EXISTS asdf7;
CREATE PROCEDURE asdf7()
BEGIN
SET @sqlstmt = 'dog';
IF 1=1 THEN
SET @sqlstmt = CONCAT('qwerty ',1,2);
END IF;
SELECT @sqlstmt;
END";
cmd.Connection = lconn;
cmd.CommandText = sXX;
cmd.ExecuteNonQuery();
}
}
以及它成功保存到db的截图:
另请注意我在您提问的评论中提到的内容。在c#端使用简单的CONCAT可以很容易地将变量插入到像tablename这样的查询中。
如果存在与Allow User Variables=True
相关的安全风险(我并不怀疑),请将此连接字符串调整仅与此例程相关,而不是全局。
这里的另一个问题是至少在我的测试中不需要DELIMITER
(类似于PHPMyAdmin和SQLFiddle)。与MySQL Workbench / Navicat / SQLYog(可能)/ Toad(可能)