C # + Pl / SQL Проблема с параметром out в хранимой процедуре

2

У меня есть хранимая процедура, которая выглядит так:

CREATE OR REPLACE PROCEDURE
Get_Username
(
    p_Username IN user.USERNAME%TYPE,
    p_ReturningUsername OUT user.Username%TYPE
)
IS
BEGIN
    SELECT username INTO p_ReturningUsername FROM user WHERE p_Username = username;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        p_ReturningUsername := null;
END;

Я выполнил его из базы данных, и он работал отлично. Когда я выполняю его из приложения С#, я не получаю никакого значения обратно.

public bool getUsername(string username)
    {
        OracleConnection connection = getConnection();
        OracleCommand oracleCommand = new OracleCommand("Get_Username", connection);
        oracleCommand.CommandType = CommandType.StoredProcedure;
        oracleCommand.Parameters.Add("p_ReturningUsername", OracleDbType.Varchar2).Direction = ParameterDirection.Output;
        oracleCommand.Parameters.Add("p_Username", OracleDbType.Varchar2).Value = username;

        try
        {
            oracleCommand.ExecuteNonQuery();
        }
        catch (OracleException ex)
        {
            MessageBox.Show("Exception Message: " + ex.Message);
            MessageBox.Show("Exception Source: " + ex.Source);
        }


        string tmp = oracleCommand.Parameters["p_ReturningUsername"].Value.ToString();
        connection.Close();
        return tmp == username;
    }

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

Пожалуйста, помогите мне, спасибо заранее.

Теги:
plsql

2 ответа

2
Лучший ответ

Как говорит @Codo, добавьте строку command.BindByName = true; , но также заменить линию

        oracleCommand.Parameters.Add("p_ReturningUsername", OracleDbType.Varchar2).Direction = ParameterDirection.Output;

с

        oracleCommand.Parameters.Add("p_ReturningUsername", OracleDbType.Varchar2, 100, null, ParameterDirection.Output);

Замените число 100 на количество символов в столбце вашего username.

Мы используем эту перегрузку метода Add чтобы мы могли указать размер выходного параметра. Это позволяет драйверу Oracle освободить достаточно места для получения значения из базы данных. null аргумент для начального значения параметра, который нас не волнует, потому что это выходной параметр, но мы должны указать его, так как нет перегрузки метода Add который принимает только имя, тип, размер и направление.

  • 0
    Большое спасибо, что это сработало, и теперь я понимаю, как это работает правильно.
0

Попробуйте этот код (я только что поменял две строки):

public bool getUsername(string username)
    {
        OracleConnection connection = getConnection();
        OracleCommand oracleCommand = new OracleCommand("Get_Username", connection);
        oracleCommand.CommandType = CommandType.StoredProcedure;
        oracleCommand.Parameters.Add("p_Username", OracleDbType.Varchar2).Value = username;
        oracleCommand.Parameters.Add("p_ReturningUsername", OracleDbType.Varchar2).Direction = ParameterDirection.Output;

        try
        {
            oracleCommand.ExecuteNonQuery();
        }
        catch (OracleException ex)
        {
            MessageBox.Show("Exception Message: " + ex.Message);
            MessageBox.Show("Exception Source: " + ex.Source);
        }


        string tmp = oracleCommand.Parameters["p_ReturningUsername"].Value.ToString();
        connection.Close();
        return tmp == username;
    }

Или добавьте:

oracleCommand.BindByName = true;

По умолчанию класс OracleCommand связывает параметры по порядку, а не по имени.

  • 0
    Это был мой оригинальный код. Я поменял его местами, потому что получаю исключение при выполнении этого кода: Сообщение об исключении: ORA-06502: PL / SQL: ошибка с числовым значением или значением ORA-06512: в «W1O67X.GET_USERNAME», строка 9 ORA-06512: в строке 1 Источник исключения: Поставщик данных Oracle для .NET, управляемый драйвер И я получаю то же самое для BindByName

Ещё вопросы

Сообщество Overcoder
Наверх
Меню