2016-10-18 5 views
1

Я пытаюсь выполнить эту команду своим приложением (C# winapp), но он должен показать ошибку, как параметр «@sqlstmt», должен быть определен, но я пытаюсь выполнить эту команду с помощью navicat, чтобы он работал хорошо, пожалуйста, помогите мнеC# Неустранимая ошибка, возникающая во время выполнения команды

"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

Все это должно быть * стенографическим строковым литералом * ('@'), так что вам не нужно программировать таким образом. Конкат может случиться или другое творчество для замены переменных. – Drew

+0

Возможно, он не нуждается в ограничительной оболочке. Я мог бы проверить его – Drew

ответ

2

Сценарий - это тот, в котором соединение mysql необходимо настроить, чтобы поддерживать поддержку пользовательских переменных. Такие, как

string connString = @"server=localhost;userid=myUser;password=thePassword;database=stackoverflow;Allow User Variables=True"; 

(обратите внимание на окончание выше). См. Руководство пользователя MySQL here относительно Allow User Variables=True. Если вы этого не сделаете, он будет забивать bigtime на знаке @, входящем в строку в пользовательской переменной.

Тест:

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(); 
    } 
} 

и скриншот его успешно сохранения в прок к БД:

enter image description here

Кроме того, обратите внимание, что я упомянул в комментариях по вашему вопросу. Вставка переменных в такой запрос, как ваш для tablename и т. Д., Проста с помощью простых CONCAT на стороне C#.

Если существует риск безопасности, связанный с Allow User Variables=True (и я не сомневаюсь, что есть), тогда эта настройка строки подключения будет иметь отношение только к этой процедуре, а не по всему миру.

Еще один вынос здесь заключается в том, что DELIMITER не требуется в моем тестировании по крайней мере (аналогично PHPMyAdmin и SQLFiddle). В отличие от MySQL Workbench/Navicat/SQLYog (возможно)/Toad (возможно)

+1

спасибо вам, что он работает^_ ^ – kanabut

Смежные вопросы