У меня есть хранимая процедура, которая выглядит так:
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 мне нужно проверить, если имя пользователя уже занято. Когда я выполняю этот код, я получаю пустую строку, когда это должно быть имя пользователя в пользовательской таблице.
Пожалуйста, помогите мне, спасибо заранее.
Как говорит @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
который принимает только имя, тип, размер и направление.
Попробуйте этот код (я только что поменял две строки):
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
связывает параметры по порядку, а не по имени.