ExecuteScalar()
Релиб
Форумы       Участники    Календарь    Кто он-лайн?
Добро пожаловать, гость ( Вход | Регистрация )
        



ExecuteScalar() Expand / Collapse
Автор
Сообщение
22.06.2006 20:12
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 09.06.2008 16:24
Сообщ.: 96, Visits: 873
У меня вопрос. Почему ExecuteScalar() ничего не возвращает. Некоторые меня узнали по теме SQLServer. В контексте это выглядит так:

OleDbCommand objCmd=new OleDbCommand("spLoginUser",this.objConn);

objCmd.CommandType=CommandType.StoredProcedure;

OleDbParameter objParam=new OleDbParameter("@Username",OleDbType.VarChar);

objParam.Direction=ParameterDirection.Input;

objParam.Value=strUsername;

objCmd.Parameters.Add(objParam);

objParam=new OleDbParameter("@Password",OleDbType.VarChar);

objParam.Direction=ParameterDirection.Input;

objParam.Value=strPassword;

objCmd.Parameters.Add(objParam);

objParam=new OleDbParameter("@UserID",OleDbType.Integer);

objParam.Direction=ParameterDirection.Output;

objCmd.Parameters.Add(objParam);

// try

// {

objConn.Open();

object obj=objCmd.ExecuteScalar();

intID=(int)(obj);

objConn.Close();

соответственно объекту objничего не применяется. Было высказано предложение что нужно применять ExecuteNonQuiry, но помучавшись так ничего я не добился. Судя по описаниям  ExecuteScalar(); более подходящий метод.

Подробности о  создаваемой хранимой процедуре смотрите в теме SQLServer.

Сообщ. #899457
23.06.2006 1:54


Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 23.04.2007 23:36
Сообщ.: 1 541, Visits: 16 997
ExecuteScalar() возвращает значение первой ячейки первой строки выборки. А выборки тут как таковой и нету.

Нужно использовать

objCmd.ExecuteNonQuery();

intId = (int)objCmd.Parameters["@UserID"].Value;

или, с учетом того, что ссылка на параметр уже есть в objParam, то

objCmd.ExecuteNonQuery();

intId = (int)objParam.Value;




Сообщ. #899466
23.06.2006 10:54
Supreme Being

Supreme Being

модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240, Visits: 65 445
1) ExecuteScalar возвращает значение из первой ячейки первой строки. У тебя же процедура не возвращает никаких записей, а только output параметр. Тебе надо использовать ExecuteNonQuery и после ее выполнения смотреть значение параметра @UserID через objParam.Value.

2) Почему для работы с SQL Server ты используешь классы OleDb вместо классов из пространства имен System.Data.SqlClient?

3) Если у тебя была старая тема, на которую ты хочешь сослаться, то не надо лениться и заставлять людей искать твою тему, а ставить на нее ссылку.

Сообщ. #899475
24.06.2006 15:18
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 09.06.2008 16:24
Сообщ.: 96, Visits: 873
1)-понял

2)я раньше так и делал, просто в одном примере недавно увидел как пользоваться OleDb и просто с прошлого примера скопировал строку
, хотя согласен что использовать System.Data.SqlClient проще

3)ок, так и буду делать

Сообщ. #899556
24.06.2006 15:49
Supreme Being

Supreme Being

модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240, Visits: 65 445
jerry (24.06.2006)
2)я раньше так и делал, просто в одном примере недавно увидел как пользоваться OleDb и просто с прошлого примера скопировал строку
, хотя согласен что использовать System.Data.SqlClient проще

Дело не в простоте. Классы OleDb* работают через универсальные драйвера OleDb, в то время как классы System.Data.SqlClient.* заточены специально под SQL Server и работают более эффективно.

Сообщ. #899560
24.06.2006 21:40
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 09.06.2008 16:24
Сообщ.: 96, Visits: 873
Понятно.

Изменил я код, только ничего пока не получается:

objCmd.ExecuteNonQuery();

object obj=objParam.Value;

intID=(int)(obj);

Проблема теперь в том, что obj присваивается значение
{System.DBNull}. Что это значит? Естесственно преобразование intID=(int)(obj); не работает.

 Наверное то что я использую не System.Data.SqlClient не должно сказываться в этой ситуации. Соединение ведь всё таки открывается.

Сообщ. #899574
24.06.2006 22:34
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 09.06.2008 16:24
Сообщ.: 96, Visits: 873
Блин, ситуация начинает проясняться. Оказывается что если в пароле и пользователе записана только одна буква, то всё работает. Например пользователь:а,пароль:п. И все нормально работает. Что-то не то с типами данных, походу varchar не подходит для этих колонок. А почему? Или в хранимых процедурах мо быть нельзя varchar использовать. Или я неправильно использую.

 А выяснилось все потому, что я создаю ещё х.проц. для добавления пользователя и в ней тоже используется varchar. И соответственно от пользователя и пароля остаются только первые буквы,  БЛИН.

Сообщ. #899575
26.06.2006 10:14
Supreme Being

Supreme Being

модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240, Visits: 65 445
1) При использовании Output параметра надо быть готовым к ситуации когда его значение будет содержать DBNull. В данном случае это сигнал, что пользователь не найден.

objCmd.ExecuteNonQuery();
if (DBNull.Value == objParam.Value)
{
// Пользователь не найден
}
else
{
int userid = Convert.ToInt32(objParam.Value);
}

2) Процедура работает только с одной буквой потому что при объявлении параметров процедуры ты забыл указать их длину. Надо примерно так.

CREATE PROCEDURE spLoginUser
@Username varchar (100),
@Password varchar (100),
@UserID int output

Само собой вместо 100 подставь реальную длину твоих полей. Также имеет смысл использовать полный конструктор OleDbParameter или SqlParameter где указывается длина поля.

Сообщ. #899616
26.06.2006 17:26
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme Being