我在C#應用程序中爲MySQL創建存儲過程。存儲過程包含一些動態創建的SQL,用於在索引存在的情況下刪除索引,然後[重新]創建它。 SQL代碼在MySQL Workbench中工作正常,但是當我從C#應用程序運行它時,出現MySQL異常。在存儲過程中使用動態SQL?
這裏是存儲過程的代碼(因爲它是在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工作臺:
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)需要連接字符串「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;
如果它有什麼區別,我使用的是MySQL Connector Net v6.5.5,MySQL Server v5.1,並在Visual Studio 2012 Pro中編寫C#應用程序。 –
你是如何在c#中創建這個存儲過程的?你能發佈實際的代碼嗎? – Riv
發佈代碼時相當困難,因爲它包含在無數類對象中,但足以說:我可以使用完全相同的代碼創建其他存儲過程,表和視圖,所以我不認爲它是C#代碼本身。但我會看看我能提取什麼。 –