Как правильно получить результат из запроса к MS SQL, записав его в соответствующие переменные?
Есть запрос вида:
SELECT * FROM ClientProfile WHERE (ClientProfile.UserID = 1) (SELECT * FROM Manager WHERE(Manager.UserID = 1) ) (SELECT * FROM Administrator WHERE (Administrator.UserID = 1))
В коде программы Windows Forms вместо *нужная таблица.UserID передаётся параметр. Если выполнить это в MS SQL, получаешь 3 таблицы: 2 пустые, так как там отсутствует пользователь с таким ID, и одна с данными, которые как раз и нужно получить, записав в переменные.
Такова попытка обработать запрос со стороны Visual Studio:
SqlCommand GetUserProfile2 = new SqlCommand("SELECT * FROM ClientProfile WHERE (ClientProfile.UserID = " + DataBank.CurrentUserID + ")" + "(SELECT * FROM Manager WHERE(Manager.UserID = " + DataBank.CurrentUserID + " ) ) " + " (SELECT * FROM Administrator WHERE (Administrator.UserID = " + DataBank.CurrentUserID + ") )", sqlConnection);
var reader2 = GetUserProfile2.ExecuteReader();
if (reader2.HasRows)
{
//Console.WriteLine("{0}\t{1}\t{2}", reader.GetName(0), reader.GetName(1), reader.GetName(2));
while (reader2.Read())
{
//if (reader2.GetInt32(0) < 0)
if (Convert.ToString(reader2["ClientID"]) != "")
{
//DataBank.CurrentClientID = Int32.Parse(reader2.GetString(0));
//DataBank.CurrentClientFullname = Convert.ToString(reader2["ClientFullName"]);
//DataBank.CurrentClientPhoneNumber = Convert.ToString(reader2["ClientPhoneNumber"]);
//DataBank.CurrentClientDateOfBirth = Convert.ToString(reader2["CurrentClientDateOfBirth"]);
//DataBank.CurrentClientEmail = Convert.ToString(reader2["Email"]);
//DataBank.CurrentClientPassport = Convert.ToString(reader2["Passport"]);
//DataBank.CurrentClientInternationalPassport = Convert.ToString(reader2["InternationalPassport"]);
DataBank.CurrentClientID = (reader2.GetInt32(0));
DataBank.CurrentClientFullname = (reader2.GetString(1));
DataBank.CurrentClientPhoneNumber = (reader2.GetString(2));
DataBank.CurrentClientDateOfBirth = reader2.GetDateTime(3).ToString();
DataBank.CurrentClientEmail = reader2.GetString(4);
DataBank.CurrentClientPassport = (reader2.GetString(5));
DataBank.CurrentClientInternationalPassport = (reader2.GetString(6));
Cl.ClientFullNameUpd.Text = DataBank.CurrentClientFullname;
Cl.ClientPhoneNumberUpd.Text = DataBank.CurrentClientPhoneNumber;
Cl.ClientDateOfBirthUpd.Text = DataBank.CurrentClientDateOfBirth;
Cl.ClientEmailUpd.Text = DataBank.CurrentClientEmail;
Cl.ClientPassportUpd.Text = DataBank.CurrentClientPassport;
Cl.ClientInternationalPassportUpd.Text = DataBank.CurrentClientInternationalPassport;
this.Hide();
Cl.Show();
}
//else if (reader2.GetString(8) != "")
else if (Convert.ToString(reader2["ManagerID"]) != "")
{
//DataBank.CurrentManagerID = Int32.Parse(reader2.GetString(0));
//DataBank.CurrentManagerFullname = Convert.ToString(reader2["ManagerFullname"]);
//DataBank.CurrentManagerEmail = Convert.ToString(reader2["Email"]);
//DataBank.CurrentManagerPhoneNumber = Convert.ToString(reader2["PhoneNumber"]);
//DataBank.CurrentManagerDateOfBirth = Convert.ToString(reader2["DateOfBirth"]);
DataBank.CurrentManagerID = (reader2.GetInt32(8)); //0
DataBank.CurrentManagerFullname = (reader2.GetString(9)); //1
DataBank.CurrentManagerEmail = (reader2.GetString(10)); //2
DataBank.CurrentManagerPhoneNumber = (reader2.GetString(11)); //3
DataBank.CurrentManagerDateOfBirth = reader2.GetDateTime(12).ToString(); //4
this.Hide();
Man.Show();
}
//else if (reader2.GetString(14)!="")
else if (Convert.ToString(reader2["AdministratorID"]) != "")
{
//DataBank.CurrentAdministratorID = Int32.Parse(reader2.GetString(0));
//DataBank.CurrentAdministratorFullname = Convert.ToString(reader2["AdministratorFullName"]);
//DataBank.CurrentAdministratorPhoneNumber = Convert.ToString(reader2["PhoneNumber"]);
//DataBank.CurrentAdministratorDateOfBirth = Convert.ToString(reader2["DateOfBirth"]);
//DataBank.CurrentAdministratorEmail = Convert.ToString(reader2["Email"]);
DataBank.CurrentAdministratorID = (reader2.GetInt32(14));
DataBank.CurrentAdministratorFullname = (reader2.GetString(15));
DataBank.CurrentAdministratorEmail = (reader2.GetString(16));
DataBank.CurrentAdministratorPhoneNumber = (reader2.GetString(17));
DataBank.CurrentAdministratorDateOfBirth = reader2.GetDateTime(18).ToString();
this.Hide();
Adm.Show();
}
//Requests.Text += (Convert.ToString(reader["RequestId"]) + " " + Convert.ToString(reader["ClientId"]) + " " + Convert.ToString(reader["TourId"]) + " " + Convert.ToString(reader["RequestDate"]) + " " + Convert.ToString(reader["ManagerId"]) + " " + Convert.ToString(reader["Acceptance"]) + "\n");
}
}
reader2.Close();
При нынешнем коде, проскакивает аутентификация клиента, и его поля успешно считываются. А вот зайти в качестве менеджера или администратора не получается. При отладке явно видны исключения:
'"reader1.Depth" выдал исключение типа "System.InvalidOperationException" '"reader1.FieldCount" выдал исключение типа "System.InvalidOperationException" '"reader1.HasRows" выдал исключение типа "System.InvalidOperationException" '"reader1.VisibleFieldCount" выдал исключение типа "System.InvalidOperationException"
Приведено к виду:
private void SignIn_Click(object sender, EventArgs e)
{
bool loginright = false;
bool passwordright = false;
string ConnectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\hzcho\source\repos\Tourist__Office\Tourist__Office\Tourist_office.mdf;Integrated Security=True";
sqlConnection = new SqlConnection(ConnectionString);
sqlConnection.Open();
sqlDataAdapter = new SqlDataAdapter("SELECT * from Users", sqlConnection);
sqlBuilder = new SqlCommandBuilder(sqlDataAdapter);
dataSet = new DataSet();
sqlDataAdapter.Fill(dataSet, "Users");
SqlCommand CheckAuth = new SqlCommand("Authentification", sqlConnection);
CheckAuth.CommandType = CommandType.StoredProcedure;
CheckAuth.Parameters.Add("@login", SqlDbType.VarChar).Value = AuthLogin.Text;
CheckAuth.Parameters.Add("@password", SqlDbType.VarChar).Value = Verification.GetSHA256Hash(AuthPassword.Text);
//CheckAuth.Parameters.Add("@Answer", SqlDbType.VarChar).Value = "";
string login = AuthLogin.Text;
string password = Verification.GetSHA256Hash(AuthPassword.Text).ToLower();
var answer = new SqlParameter("@Answer", SqlDbType.NVarChar);
answer.Direction = System.Data.ParameterDirection.Output;
answer.Size = 64;
CheckAuth.Parameters.Add(answer);
CheckAuth.ExecuteNonQuery();
var res = answer.Value.ToString();
{
if ((res == "Отсутствует в базе"))
//if (Int32.Parse(reader.GetString(0)) == 0)
{
MessageBox.Show("Отсутствует в базе");
}
else if ((res == "Присутствует в базе"))
{
loginright = true;
passwordright = true;
//MessageBox.Show("Отсутствует в базе");
SqlCommand GetIdUser = new SqlCommand("SELECT IdUser from Users Where Login = '" + login + "'" + " AND Password = '" + password + "'", sqlConnection);
//sqlDataAdapter = new SqlDataAdapter
//dataSet = new DataSet();
//using (SqlConnection connection = new SqlConnection(ConnectionString))
{
//connection.Open();
//SqlCommand FillRequests = new SqlCommand("ShowAllRequests", connection);
//FillRequests.CommandType = CommandType.StoredProcedure;
// указываем, что команда представляет хранимую процедуру
//SqlCommand GetUserProfile1 = new SqlCommand("SELECT IdUser from Users Where Login =" + AuthLogin.Text + " AND Password = " + Verification.GetSHA256Hash(AuthPassword.Text), sqlConnection);
var reader1 = GetIdUser.ExecuteReader();
if (reader1.HasRows)
{
//Console.WriteLine("{0}\t{1}\t{2}", reader.GetName(0), reader.GetName(1), reader.GetName(2));
while (reader1.Read())
{
DataBank.CurrentUserID = (reader1.GetInt32(0));
}
}
reader1.Close();
string GetProfileData = "SELECT * FROM ClientProfile WHERE ClientProfile.UserID = @UserId " +
"SELECT * FROM Manager WHERE Manager.UserID = @UserId " +
"SELECT * FROM Administrator WHERE Administrator.UserID = @UserId";
using (var GetUserProfile = new SqlCommand(GetProfileData, sqlConnection))
{
GetUserProfile.Parameters.Add("UserId", SqlDbType.Int).Value = DataBank.CurrentUserID;
using (var reader2 = GetUserProfile.ExecuteReader())
{
while (reader2.Read())
{
DataBank.CurrentClientID = reader2.GetInt32(0);
DataBank.CurrentClientFullname = reader2.GetString(1);
DataBank.CurrentClientPhoneNumber = reader2.GetString(2);
DataBank.CurrentClientDateOfBirth = reader2.GetDateTime(3).ToString();
DataBank.CurrentClientEmail = reader2.GetString(4);
DataBank.CurrentClientPassport = reader2.GetString(5);
DataBank.CurrentClientInternationalPassport = reader2.GetString(6);
Cl.ClientFullNameUpd.Text = DataBank.CurrentClientFullname;
Cl.ClientPhoneNumberUpd.Text = DataBank.CurrentClientPhoneNumber;
Cl.ClientDateOfBirthUpd.Text = DataBank.CurrentClientDateOfBirth;
Cl.ClientEmailUpd.Text = DataBank.CurrentClientEmail;
Cl.ClientPassportUpd.Text = DataBank.CurrentClientPassport;
Cl.ClientInternationalPassportUpd.Text = DataBank.CurrentClientInternationalPassport;
this.Hide();
Cl.Show();
}
if (reader2.NextResult()) // move to Manager data
{
while (reader2.Read())
{
// Обратите внимание: индексы колонок снова с нуля
DataBank.CurrentManagerID = reader2.GetInt32(0);
DataBank.CurrentManagerFullname = reader2.GetString(1);
DataBank.CurrentManagerEmail = reader2.GetString(2);
DataBank.CurrentManagerPhoneNumber = reader2.GetString(3);
DataBank.CurrentManagerDateOfBirth = reader2.GetDateTime(4).ToString();
Man.ManagerFullName.Text = DataBank.CurrentClientFullname;
Man.ManagerPhoneNumber.Text = DataBank.CurrentClientPhoneNumber;
Man.ManDateOfBirth.SetDate(reader2.GetDateTime(4));
Man.ManagerEmail.Text = DataBank.CurrentClientEmail;
this.Hide();
Man.Show();
}
}
if (reader2.NextResult()) // move to Administrator data
{
while (reader2.Read())
{
// Обратите внимание: индексы колонок снова с нуля
DataBank.CurrentAdministratorID = reader2.GetInt32(0);
DataBank.CurrentAdministratorFullname = reader2.GetString(1);
DataBank.CurrentAdministratorEmail = reader2.GetString(2);
DataBank.CurrentAdministratorPhoneNumber = reader2.GetString(3);
DataBank.CurrentAdministratorDateOfBirth = reader2.GetDateTime(4).ToString();
//DataBank.CurrentManagerID = reader.GetInt32(0);
//DataBank.CurrentManagerFullname = reader.GetString(1);
//DataBank.CurrentManagerEmail = reader.GetString(2);
//DataBank.CurrentManagerPhoneNumber = reader.GetString(3);
//DataBank.CurrentManagerDateOfBirth = reader.GetDateTime(4).ToString();
Adm.UpdAdministratorFullName.Text = DataBank.CurrentClientFullname;
Adm.UpdAdministratorPhoneNumber.Text = DataBank.CurrentClientPhoneNumber;
Adm.AdmDateOfB.SetDate(reader2.GetDateTime(4));
Adm.UpdAdministratorEmail.Text = DataBank.CurrentClientEmail;
this.Hide();
Adm.Show();
}
}
}
}
}
}
}
//sqlConnection.Close();
if (!loginright || !passwordright)
MessageBox.Show("Неправильный логин или пароль");
}
Результат: при вводе логина и пароля, перехода на другую форму(Cl,Man,Adm), не происходит, ни на одну из точек остановки при отладке не реагирует. При старом коде переходил на форму клиента(Cl).
Вынес отдельно функции проверки на наличие пользователя в базе и получения его ID, вызываю их в обработчике кнопки. Код всё так же не отрабатывает: игнорирует точки остановки, перехода на другие формы не происходит.
private String IsInBase()
{
string ConnectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\hzcho\source\repos\Tourist__Office\Tourist__Office\Tourist_office.mdf;Integrated Security=True";
sqlConnection = new SqlConnection(ConnectionString);
sqlConnection.Open();
sqlDataAdapter = new SqlDataAdapter("SELECT * from Users", sqlConnection);
sqlBuilder = new SqlCommandBuilder(sqlDataAdapter);
dataSet = new DataSet();
sqlDataAdapter.Fill(dataSet, "Users");
SqlCommand CheckAuth = new SqlCommand("Authentification", sqlConnection);
CheckAuth.CommandType = CommandType.StoredProcedure;
CheckAuth.Parameters.Add("@login", SqlDbType.VarChar).Value = AuthLogin.Text;
CheckAuth.Parameters.Add("@password", SqlDbType.VarChar).Value = Verification.GetSHA256Hash(AuthPassword.Text);
//CheckAuth.Parameters.Add("@Answer", SqlDbType.VarChar).Value = "";
string login = AuthLogin.Text;
string password = Verification.GetSHA256Hash(AuthPassword.Text).ToLower();
var answer = new SqlParameter("@Answer", SqlDbType.NVarChar);
answer.Direction = System.Data.ParameterDirection.Output;
answer.Size = 64;
CheckAuth.Parameters.Add(answer);
CheckAuth.ExecuteNonQuery();
var res = answer.Value.ToString();
return res;
}
private void GetIdUser()
{
string login = AuthLogin.Text;
string password = Verification.GetSHA256Hash(AuthPassword.Text).ToLower();
//MessageBox.Show("Отсутствует в базе");
SqlCommand GetIdUser = new SqlCommand("SELECT IdUser from Users Where Login = '" + login + "'" + " AND Password = '" + password + "'", sqlConnection);
//sqlDataAdapter = new SqlDataAdapter
//dataSet = new DataSet();
//using (SqlConnection connection = new SqlConnection(ConnectionString))
{
//connection.Open();
//SqlCommand FillRequests = new SqlCommand("ShowAllRequests", connection);
//FillRequests.CommandType = CommandType.StoredProcedure;
// указываем, что команда представляет хранимую процедуру
//SqlCommand GetUserProfile1 = new SqlCommand("SELECT IdUser from Users Where Login =" + AuthLogin.Text + " AND Password = " + Verification.GetSHA256Hash(AuthPassword.Text), sqlConnection);
var reader1 = GetIdUser.ExecuteReader();
if (reader1.HasRows)
{
//Console.WriteLine("{0}\t{1}\t{2}", reader.GetName(0), reader.GetName(1), reader.GetName(2));
while (reader1.Read())
{
DataBank.CurrentUserID = (reader1.GetInt32(0));
}
}
reader1.Close();
}
}
private void SignIn_Click(object sender, EventArgs e)
{
//bool loginright = false;
//bool passwordright = false;
bool loginright = false;
bool passwordright = false;
string login = AuthLogin.Text;
string password = Verification.GetSHA256Hash(AuthPassword.Text).ToLower();
//string ConnectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\hzcho\source\repos\Tourist__Office\Tourist__Office\Tourist_office.mdf;Integrated Security=True";
//sqlConnection = new SqlConnection(ConnectionString);
//sqlConnection.Open();
//sqlDataAdapter = new SqlDataAdapter("SELECT * from Users", sqlConnection);
//sqlBuilder = new SqlCommandBuilder(sqlDataAdapter);
//dataSet = new DataSet();
//sqlDataAdapter.Fill(dataSet, "Users");
//SqlCommand CheckAuth = new SqlCommand("Authentification", sqlConnection);
//CheckAuth.CommandType = CommandType.StoredProcedure;
//CheckAuth.Parameters.Add("@login", SqlDbType.VarChar).Value = AuthLogin.Text;
//CheckAuth.Parameters.Add("@password", SqlDbType.VarChar).Value = Verification.GetSHA256Hash(AuthPassword.Text);
////CheckAuth.Parameters.Add("@Answer", SqlDbType.VarChar).Value = "";
//string login = AuthLogin.Text;
//string password = Verification.GetSHA256Hash(AuthPassword.Text).ToLower();
//var answer = new SqlParameter("@Answer", SqlDbType.NVarChar);
//answer.Direction = System.Data.ParameterDirection.Output;
//answer.Size = 64;
//CheckAuth.Parameters.Add(answer);
//CheckAuth.ExecuteNonQuery();
//var res = answer.Value.ToString();
var res = IsInBase();
{
if ((res == "Отсутствует в базе"))
//if (Int32.Parse(reader.GetString(0)) == 0)
{
MessageBox.Show("Отсутствует в базе");
}
else if ((res == "Присутствует в базе"))
{
GetIdUser();
string ProfileData = "SELECT * FROM ClientProfile WHERE ClientProfile.UserID = @UserId " +
"SELECT * FROM Manager WHERE Manager.UserID = @UserId " +
"SELECT * FROM Administrator WHERE Administrator.UserID = @UserId";
using (var GetUserProfile = new SqlCommand(ProfileData, sqlConnection))
{
GetUserProfile.Parameters.Add("UserId", SqlDbType.Int).Value = DataBank.CurrentUserID;
using (var reader2 = GetUserProfile.ExecuteReader())
{
while (reader2.Read())
{
DataBank.CurrentClientID = reader2.GetInt32(0);
DataBank.CurrentClientFullname = reader2.GetString(1);
DataBank.CurrentClientPhoneNumber = reader2.GetString(2);
DataBank.CurrentClientDateOfBirth = reader2.GetDateTime(3).ToString();
DataBank.CurrentClientEmail = reader2.GetString(4);
DataBank.CurrentClientPassport = reader2.GetString(5);
DataBank.CurrentClientInternationalPassport = reader2.GetString(6);
Cl.ClientFullNameUpd.Text = DataBank.CurrentClientFullname;
Cl.ClientPhoneNumberUpd.Text = DataBank.CurrentClientPhoneNumber;
Cl.ClientDateOfBirthUpd.Text = DataBank.CurrentClientDateOfBirth;
Cl.ClientEmailUpd.Text = DataBank.CurrentClientEmail;
Cl.ClientPassportUpd.Text = DataBank.CurrentClientPassport;
Cl.ClientInternationalPassportUpd.Text = DataBank.CurrentClientInternationalPassport;
this.Hide();
Cl.Show();
}
if (reader2.NextResult()) // move to Manager data
{
while (reader2.Read())
{
// Обратите внимание: индексы колонок снова с нуля
DataBank.CurrentManagerID = reader2.GetInt32(0);
DataBank.CurrentManagerFullname = reader2.GetString(1);
DataBank.CurrentManagerEmail = reader2.GetString(2);
DataBank.CurrentManagerPhoneNumber = reader2.GetString(3);
DataBank.CurrentManagerDateOfBirth = reader2.GetDateTime(4).ToString();
Man.ManagerFullName.Text = DataBank.CurrentClientFullname;
Man.ManagerPhoneNumber.Text = DataBank.CurrentClientPhoneNumber;
Man.ManDateOfBirth.SetDate(reader2.GetDateTime(4));
Man.ManagerEmail.Text = DataBank.CurrentClientEmail;
this.Hide();
Man.Show();
}
}
if (reader2.NextResult()) // move to Administrator data
{
while (reader2.Read())
{
// Обратите внимание: индексы колонок снова с нуля
DataBank.CurrentAdministratorID = reader2.GetInt32(0);
DataBank.CurrentAdministratorFullname = reader2.GetString(1);
DataBank.CurrentAdministratorEmail = reader2.GetString(2);
DataBank.CurrentAdministratorPhoneNumber = reader2.GetString(3);
DataBank.CurrentAdministratorDateOfBirth = reader2.GetDateTime(4).ToString();
//DataBank.CurrentManagerID = reader.GetInt32(0);
//DataBank.CurrentManagerFullname = reader.GetString(1);
//DataBank.CurrentManagerEmail = reader.GetString(2);
//DataBank.CurrentManagerPhoneNumber = reader.GetString(3);
//DataBank.CurrentManagerDateOfBirth = reader.GetDateTime(4).ToString();
Adm.UpdAdministratorFullName.Text = DataBank.CurrentClientFullname;
Adm.UpdAdministratorPhoneNumber.Text = DataBank.CurrentClientPhoneNumber;
Adm.AdmDateOfB.SetDate(reader2.GetDateTime(4));
Adm.UpdAdministratorEmail.Text = DataBank.CurrentClientEmail;
this.Hide();
Adm.Show();
}
}
}
}
}
//sqlConnection.Close();
if (!loginright || !passwordright)
MessageBox.Show("Неправильный логин или пароль");
}
}
Ответы (1 шт):
Вы используете batch - пакет запросов. Для получения доступа к следующему набору данных нужно использовать метод NextResult.
Вы же использовали параметры при работе с хранимой процедурой, почему не используете здесь?
Ресурсы надо освобождать. Я показал, как это делать, применив оператор using.
SqlConnection тоже нужно освобождать. Но оно, похоже, создаётся у вас где-то в другом месте (обычно это неправильно).
В целом код может выглядеть как-то так:
string sql =
"SELECT * FROM ClientProfile WHERE ClientProfile.UserID = @UserId; " +
"SELECT * FROM Manager WHERE Manager.UserID = @UserId; " +
"SELECT * FROM Administrator WHERE Administrator.UserID = @UserId";
using (var command = new SqlCommand(sql, sqlConnection))
{
command.Parameters.Add("UserId", SqlDbType.Int).Value = DataBank.CurrentUserID;
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
DataBank.CurrentClientID = reader.GetInt32(0);
DataBank.CurrentClientFullname = reader.GetString(1);
DataBank.CurrentClientPhoneNumber = reader.GetString(2);
DataBank.CurrentClientDateOfBirth = reader.GetDateTime(3);
DataBank.CurrentClientEmail = reader.GetString(4);
DataBank.CurrentClientPassport = reader.GetString(5);
DataBank.CurrentClientInternationalPassport = reader.GetString(6);
// тут остальной код
}
if (reader.NextResult()) // move to Manager data
{
while (reader.Read())
{
// Обратите внимание: индексы колонок снова с нуля
DataBank.CurrentManagerID = reader.GetInt32(0);
DataBank.CurrentManagerFullname = reader.GetString(1);
DataBank.CurrentManagerEmail = reader.GetString(2);
DataBank.CurrentManagerPhoneNumber = reader.GetString(3);
DataBank.CurrentManagerDateOfBirth = reader.GetDateTime(4);
// ...
}
}
if (reader.NextResult()) // move to Administrator data
{
while (reader.Read())
{
// Обратите внимание: индексы колонок снова с нуля
DataBank.CurrentAdministratorID = reader.GetInt32(0);
DataBank.CurrentAdministratorFullname = reader.GetString(1);
DataBank.CurrentAdministratorEmail = reader.GetString(2);
DataBank.CurrentAdministratorPhoneNumber = reader.GetString(3);
DataBank.CurrentAdministratorDateOfBirth = reader.GetDateTime(4);
// ...
}
}
}
}
В действии я код не проверял. Надеюсь, сможете одолеть нюансы.