Вызов хранимой процедуры с выводом

#c# #sql-server #stored-procedures

#c# #sql-сервер #хранимые процедуры

Вопрос:

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

Код, который я использую, является модифицированной частью, которую я использую для регистрации пользователя. В cmd происходит ошибка.Часть моего кода ExecuteReader.

 protected void btn_login_Click(object sender, ImageClickEventArgs e)
{
    //Actions after Submit button is clicked
    Page.Validate(((ImageButton)sender).ValidationGroup);

    if (Page.IsValid)
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnectString"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand("usp_validateUsers", conn);
            //Input Values
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("username", Uname.Text);
            cmd.Parameters.AddWithValue("password", pwd.Text);
            //Return Values
            SqlParameter retParam = cmd.Parameters.Add("@RetVal", SqlDbType.Int);
            retParam.Direction = ParameterDirection.ReturnValue;
            SqlParameter acsParam = cmd.Parameters.Add("@ac_status", SqlDbType.Int);
            acsParam.Direction = ParameterDirection.Output;
            SqlParameter nikParam = cmd.Parameters.Add("@memb_name", SqlDbType.VarChar);
            nikParam.Direction = ParameterDirection.Output;

            try
            {
                // Open Connection and execute Stored Proc
                conn.Open();
                ///////////SOMETHING GOES WRONG HERE///////////////
                cmd.ExecuteReader();

                //Retrieve Data
                int retVal = (int)retParam.Value;
                string nickname = nikParam.Value.ToString();
                string ac_stats = acsParam.Value.ToString();

                if (retVal != 0)
                {
                    //Invalid Username or password
                }
                else
                {
                    //Login User
                }
            }

            catch (Exception Error)
            {
                lbl_login.Text = "An error occured, please try again later";
                debug.Text = Error.Message;
            }

            finally
            {
                debug.Text = "n Clossing Connection";
                if (conn.State == System.Data.ConnectionState.Open)
                {
                    conn.Close();
                }

            }
        }
    }
}
  

Когда я просто хочу получить возвращаемое значение, я просто использую cmd.ExecuteScalar(); Я знаю, как получать данные при передаче SQL-запроса в базу данных SQL, но, похоже, при использовании хранимых процедур все по-другому..

РЕДАКТИРОВАНИЕ, вероятно, могло бы еще больше улучшить этот код, но оно действительно делает то, что должно делать.

 ALTER PROCEDURE dbo.usp_validateUsers

@username varchar(10),
@password varchar(10),
@ac_status char(1) OUTPUT,
@memb_name varchar(15) OUTPUT

AS
IF EXISTS(SELECT * FROM MEMB_INFO WHERE (memb___id = @username))
BEGIN
    SELECT @ac_status = ac_status, @memb_name = memb_name
    FROM MEMB_INFO
    WHERE (memb___id = @username) AND (memb__pwd = @password)
    RETURN 0
END

ELSE
BEGIN
    return 1
END
  

Когда я использую точки останова для перехвата возможных исключений в Visual Studio, это дает мне:
Строка[4]: свойство Size имеет недопустимый размер 0

Комментарии:

1. Какую ошибку вы получаете при запуске ExecuteReader ?

2. что-то насчет строки [4], имеющей неправильный размер 0.

3. ваши строковые параметры должны иметь длину.

4. Как глупо с моей стороны переоценивать это… Спасибо! Я знал, что это как-то связано с этими значениями там, думать, что это было так просто..

Ответ №1:

Упомянутая вами ошибка может быть вызвана тем фактом, что вы не указываете размер своих VarChar параметров. Вместо того, чтобы иметь строки, подобные этой:

 SqlParameter nikParam = cmd.Parameters.Add("@memb_name", SqlDbType.VarChar);
  

Попробуйте это:

 SqlParameter nikParam = cmd.Parameters.Add("@memb_name", SqlDbType.VarChar, 15);
  

Ответ №2:

Вам нужно создать SqlDataReader.

Из всех тонкостей использования хранимых процедур в C #

Класс SqlDataReader используется для чтения только прямого потока записей, возвращаемых из базы данных. Экземпляр объекта SqlDataReader создается не напрямую через конструктор (отсюда отсутствие нового ключевого слова), а скорее через метод ExecuteReader объекта SqlCommand. Перед вызовом метода ExecuteReader устанавливается соединение с базой данных с использованием метода Open объекта SqlConnection.

Попробуйте

 SqlDataReader drLogins;
Conn.Open();
drLogins = cmd.ExecuteReader();
  

Комментарии:

1. Это вообще не было проблемой, все равно спасибо!

Ответ №3:

Ваш @ac_status определяется как целое число в параметре. измените ее символ или строку.

 SqlParameter acsParam = cmd.Parameters.Add("@ac_status", SqlDbType.Int);
  

Комментарии:

1. Я виноват, но это изменяет строку [4] на строку[3] Ошибка: P