我正在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
编辑:感谢Reubz,我得到了代码。需要两个部分:(1)连接字符串需要“允许用户变量=真;”包括,和(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;
答案 0 :(得分:1)
根据我们的聊天:
您必须将@符号用于用户定义的变量s,以便将其与系统变量区分开来。但是,在较新版本的MySQL连接器中,默认情况下禁用用户定义的变量。要启用它,您需要更改连接字符串并添加User Variables = True参数。