2014-11-24 1 views
2

Я пишу надстройку для Enterprise Architect, и мне нужно манипулировать внутренними скриптами. Я хотел бы добавить свою собственную функцию в существующий скрипт.Получить строку с избыточным синтаксисом sql update

скрипты хранятся в таблице t_script в колонке Script.

К сожалению, скрипты не отображаются в API, поэтому мне придется обойти это и использовать запрос обновления в базе данных для обновления сценария.

Проблема заключается в том, что скрипты имеют тенденцию использовать множество символов, которые могут представлять проблему при использовании их в запросе обновления sql, но я не очень хочу писать свою собственную функцию эвакуации.

Так что я попытался было это

public void addCode(string functionCode) 
{ 
    this._code += functionCode; 
    SqlCommand sqlCommand = new SqlCommand("update t_script set script = @functionCode where ScriptID = " + this.scriptID); 
    sqlCommand.Parameters.AddWithValue("@functionCode",this._code); 
    this.model.executeSQL(sqlCommand.CommandText); 
} 

Я надеялся, что sqlCommand.CommandText даст мне реальную SQL строку, которая собирается быть выполнена, но это не так. В основном это одна и та же строка, с которой я ее создал, и она не заменила «@functionCode».

Дополнительная трудность состоит в том, что моя SQL строка должна работать на всех типах СУБД, поддерживаемых EA

  • SQL Server 2000, 2005, 2008 и 2012
  • MySQL
  • Oracle 9i, 10g, 11g и 12с
  • PostgreSQL
  • MSDE
  • Sybase Adaptive Server Anywhere
  • MS Access
  • Progress OpenEdge
  • Firebird

Кто-нибудь есть лучшее решение, то писать свою собственную функцию побега?

+1

Ожидайте ожидаемого ;-) Конечно, вы могли бы попросить Sparxians предложить свою внутреннюю процедуру. Вероятно, так же, как попросить Папу совершить ошибку.Так что пока делайте то, что вы ожидали в любом случае: напишите свой собственный материал> :-( –

+0

Я думаю, что единственным действительно безопасным и разумным способом сделать это будет использование bind-Variables в Select. Вам не потребуется NO Escaping. нужно сохранить переменные где-то ... – Falco

+0

@Falco Как вы понимаете? Проблема в том, что мне нужна полная строка SQL, чтобы передать объект репозитория. У меня нет контроля над фактическим исполнением строки. –

ответ

1

Поскольку я действительно не нашел какую-то существующую функциональность, мне приходилось прибегать к написанию моей собственной функции эвакуации.

Это то, что я придумал. Это, кажется, работает на MS-Access, FireBird, SLQ Server, MySQL и Oracle (я не проверял другие)

/// <summary> 
/// escapes a literal string so it can be inserted using sql 
/// </summary> 
/// <param name="sqlString">the string to be escaped</param> 
/// <returns>the escaped string</returns> 
public string escapeSQLString(string sqlString) 
{ 
    string escapedString = sqlString; 
    switch (this.repositoryType) 
    { 
     case RepositoryType.MYSQL: 
     case RepositoryType.POSTGRES: 
      // replace backslash "\" by double backslash "\\" 
      escapedString = escapedString.Replace(@"\",@"\\"); 
     break; 
    } 
    // ALL DBMS types: replace the single qoutes "'" by double single quotes "''" 
    escapedString = escapedString.Replace("'","''"); 
    return escapedString; 
} 

EDIT: Исправлен код после выполнения комментарии по поводу обратной косой черты отводящей

+1

Вы уверены, что это работает? Обратная косая черта не является Escape Ch aracter в Oracle-Strings! Если я хочу вставить Test '\ в Oracle, вы замените его на INSERT' Test '' \\ ', и он будет дважды вставлять Backslash! – Falco

+0

@ Falco Нет, я не уверен. Должен признать, что я не тестировал обратную косую черту в Oracle. Спасибо за подсказку. Я проверю его и отчитаю. –

+1

Я считаю, что единственный правильный способ - использовать функцию [Repository.RepositoryType()] (http://www.sparxsystems.com/enterprise_architect_user_guide/11/automation_and_scripting/repository3.html), чтобы определить вкус SQL, а затем использовать строку операторов конкатенации и ascii для функций char для построения строкового литерала. Они будут отличаться для каждого используемого SQL-сервера – xmojmr

0

Я не думаю, что вы должны ожидать SqlCommand для разрешения параметров, которые выполняются на сервере.

Что касается проблемы с несколькими СУБД, я бы посмотрел на что-то вроде NHibernate. Это не то, что вы можете просто зайти в последнюю минуту, но он поддерживает большинство баз данных EA.

+0

Спасибо для предложения, я рассмотрю его, но сейчас мне кажется, что это похоже на использование пушки, пытающейся убить комара. –

+0

Хм. По крайней мере, для MySQL вам нужно избегать SQL на стороне клиента и переместить результат поверх на сервере. AFAIK нет ничего похожего на «здесь SQL с заполнителями, а вот параметры». Вы используете mysql_real_query и помещаете отредактированный SQL в. –