ORA-01008 со всеми связанными переменными - PullRequest
7 голосов
/ 15 апреля 2011

Я использую System.Data.OracleClient, который выполняет привязку параметров по имени и проверяет синхронизацию CommandText и Parameters:

    public string CommandText { get; set; }
    public IEnumerable<OracleParameter> Parameters { get; set; }

    private void VerifyThatAllParametersAreBound()
    {
        var variableNames = Regex.Matches(CommandText, ":\\w+")
            .Cast<Match>().Select(m => m.Value).ToArray();
        var parameteterNames = Parameters.Select(p => p.ParameterName).ToArray();

        var unboundVariables = variableNames.Except(parameteterNames).ToArray();
        if (unboundVariables.Length > 0)
        {
            throw new Exception("Variable in CommandText missing parameter: "
                + string.Join(", ", unboundVariables) + ".");
        }

        var unboundParameters = parameteterNames.Except(variableNames).ToArray();
        if (unboundParameters.Length > 0)
        {
            throw new Exception("Parameter that is not used in CommandText: "
                + string.Join(", ", unboundParameters) + ".");
        }
    }

Еще один запрос выбрасывает ORA-01008: not all variables bound. При ручной вставке значений параметров в ошибочный CommandText выполняется запрос, поэтому значения CommandText и Parameters должны быть в порядке. Я использую: в качестве префикса для переменных и имен параметров, и он работает для других запросов.

Как я могу определить причину этого исключения?

Ответы [ 3 ]

9 голосов
/ 18 апреля 2011

Ошибка не указала DBNull.Value для нулевых значений. Так

new OracleParameter(":Foo", item.Foo)

пришлось предварительно поставить с

item.Foo == null 
    ? new OracleParameter(":Foo", DBNull.Value) 
    : new OracleParameter(":Foo", item.Foo)

Я думаю, что раньше он работал с ODT.NET без нулевых проверок, но не подтвердил это. Очевидно, System.Data.OracleClient сбрасывает параметры с нулевым значением.

3 голосов
/ 06 декабря 2012

Если вы передадите null в качестве значения параметра, вы получите «Не все переменные связаны». Если вы передадите DBNull.Value , вы получите ошибку времени выполнения где-то в OracleClient. Чтобы передать NULL, используйте string.Empty , OracleClient преобразует его в NULL для любого типа базы данных.

0 голосов
/ 15 апреля 2011

Я полагаю, что Microsoft устарела OracleClient как часть ADO.NET около 2 лет назад.

Вы можете рассмотреть возможность использования компонентов доступа к данным Oracle (ODAC odp.net). Легко построить (и проверить количество) параметров с помощью класса OracleParameter. Установки и установки документов найдены здесь . О, вы также можете получить поддержку их Entity Framework (и LINQ) (все еще бета, я думаю?).

Что-то всерьез обдумать.

...