#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