Попытка создать несколько общий метод запроса - PullRequest
0 голосов
/ 28 марта 2012

Я хотел заменить не только значения, хранящиеся в столбцах, параметрами, но и имена таблиц, имена столбцов и т. Д., Поэтому я попытался это сделать:

    // Can get any string value based on any string key with this function
    public string GetValForKeyVal(string ATable, string AKeyVal, string AColumnToQuery, string AColumnToReturn) {
        String qry = "SELECT :ColOfInterest FROM :TableToQuery WHERE :KeyValColumn = :KeyVal";
        OracleCommand cmd = new OracleCommand(qry, con);
        cmd.CommandType = CommandType.Text;
        OracleParameter opColOfInterest = cmd.Parameters.Add("ColOfInterest", OracleDbType.Varchar2,
          AColumnToReturn, ParameterDirection.Input);
        OracleParameter opTableToQuery = cmd.Parameters.Add("TableToQuery", OracleDbType.Varchar2,
          ATable, ParameterDirection.Input);
        OracleParameter opKeyValColumn = cmd.Parameters.Add("KeyValColumn", OracleDbType.Varchar2,
          AColumnToQuery, ParameterDirection.Input);
        OracleParameter opKeyVal = cmd.Parameters.Add("KeyVal", OracleDbType.Varchar2,
          AKeyVal, ParameterDirection.Input);
        return cmd.ExecuteScalar().ToString();
    }

... но получите, "ORA-00903 invalid table name"

Итак, я попытался сделать это на C #:

    public string GetValForKeyVal(string ATable, string AKeyVal, string AColumnToQuery, string AColumnToReturn) {
        String qry = String.Format("SELECT {0} FROM {1} WHERE {2} = {3}", AColumnToReturn, ATable, AColumnToQuery, AKeyVal);
        OracleCommand cmd = new OracleCommand(qry, con);
        cmd.CommandType = CommandType.Text;
        return cmd.ExecuteScalar().ToString();
    }

... но это тоже не удалось, на самом деле, с "ORA-00904 "WHYAMINOTQUOTINGTHEDOT"."EXE": invalid identifier"

Я лаю не на том дереве или просто использую неправильный способ подать кошку?

В старые времена (Delphi) вы могли сделать строку безопасной для передачи в механизм БД, заключив ее в нечто вроде QueryStr(). Есть ли аналогичная вспомогательная функция для C#/Oracle?

1 Ответ

4 голосов
/ 28 марта 2012

Нельзя использовать параметры для замены имен таблиц и столбцов в Oracle. Одним из основных преимуществ использования параметризованных запросов с точки зрения базы данных является то, что Oracle может один раз проанализировать запрос (помимо прочего, сгенерировать план запроса), а затем выполнить его много раз с различными значениями параметров. Если таблица или столбцы изменятся, для этого потребуется новый жесткий анализ запроса, чтобы он не имел права быть переменной связывания.

Можете ли вы объяснить немного больше о проблеме, которую вы пытаетесь решить? Кажется необычным то, что вы захотите написать код, который мог бы запросить произвольный столбец произвольной таблицы - что обычно подразумевает, что у вас есть несколько разных таблиц, которые хранят один и тот же базовый вид данных, и в этом случае вам, как правило, будет лучше служил пересмотром нормализации вашей модели данных. Если вы хотите определить, является ли конкретное имя таблицы или имя столбца безопасным для передачи в базу данных с точки зрения внедрения SQL, вы можете использовать DBMS_ASSERT пакет , но в этот момент вам может быть лучше обслужен только запрос ALL_TAB_COLUMNS для указанного имени таблицы и имени столбца, чтобы увидеть, есть ли в базе данных столбцы AColumnToReturn и AColumnToQuery в ATable.

...