При вызове хранимой процедуры в программе ,первый её вызов возвращает данные вызова предыдущей использованной хранимой процедуры
Пишу приложение - чат, что-то на подобии telegram desktop на минималках. Реализовано все это путем написания клиентской и серверной части. Серверная часть общается с клиентской с помощью Socket, а с базой данных через вызовы хранимых процедур using System.Data.SqlClient;
Распознавание команд сервером происходит при помощи тэгов
В приложении постоянно появляется ошибка, что при вызове одной хранимой процедуры, при первом ее вызове она выдаст данные последней использованной хранимой процедуры
Класс для работы с БД:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data;
namespace ConsoleChatServer
{
class Database_work // класс для работы с sql сервером
{
readonly SqlConnection _connection; //объект соединения sql только для чтения
//Конструктор------------------------------
public Database_work()
{
this._connection = new SqlConnection("Server="+Configuration.SQL_Address_global+"\\" + Configuration.SQL_Exemp_name_global + ";" + "User Id=" + Configuration.SQL_User_ID_global + ";" + "password=" + Configuration.SQL_Password_global + ";" + "initial catalog=" + Configuration.SQL_Catalog_global + ";"); // Формирование строки подключения
}
//-----------------------------------------
public string SP_ADD_USER(string user_name,string password) //добавление пользователя в БД возвращает 1 при успешном добавлении и 0 если такой пользователь существует
{
SqlCommand command = new SqlCommand();
command.CommandText = "SP_ADD_USER";
command.CommandType = CommandType.StoredProcedure;
command.Connection = _connection;
command.Parameters.AddWithValue("@USER_NAME", user_name);
command.Parameters.AddWithValue("@PASSWORD", password);
string result = "0";
try
{
_connection.Open();
}
catch (Exception e)
{
Console.WriteLine("Ошибка: {0}", e.Message);
}
finally
{
try
{
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
while (reader.Read())
{
result = reader.GetValue(0).ToString();
if (result == "1")
{
Console.WriteLine("Пользователь: " + user_name + " зарегистрирован в системе с паролем: " + password);
}
else
{
Console.WriteLine("Пользователь: " + user_name + " неудачная попытка регистрации в системе с паролем: " + password);
}
}
_connection.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return result; //Возвращение результата
}
public string SP_USER_AUTORIZATION(string user_name, string password) //Возвращает строку результат_выполнения(1/0)&айди_пользователя&username
{
SqlCommand command = new SqlCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "SP_USER_AUTORIZATION";
command.Parameters.AddWithValue("@USER_NAME", user_name);
command.Parameters.AddWithValue("@password", password);
command.Connection = _connection;
string result = "0";
string Result_fulfillment; //переменная для результата выполнения 1 - столбец
string user_id; // переменная для user_id - 2 столбец
string username;// переменная для username - 3 столбец
try
{
_connection.Open();
}
catch (Exception e)
{
Console.WriteLine("Ошибка: {0}", e.Message);
}
finally
{
try
{
//SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
while (reader.Read())
{
Result_fulfillment = (string)reader.GetValue(0).ToString();
user_id = (string)reader.GetValue(1).ToString();
username = (string)reader.GetValue(2).ToString();
result = Result_fulfillment + Configuration.znak_separator + user_id + Configuration.znak_separator + username;
if ((string)Result_fulfillment == "1")
{
Console.WriteLine("Пользователь: " + username + " успешно авторизован в системе!");
}
if ((string)Result_fulfillment == "0")
{
Console.WriteLine("Пользователь: " + username + " неудачная попытка авторизации!");
}
}
_connection.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return result;
}
public string[] SP_SEARCH_USER(string user_name) //Поиск пользователей в бд //ВОЗВРАЩАЕТ ТАБЛИЦУ МАССИВОМ
//id&username|
//id&username|
//id&username|
//id&username|
//id&username|
{
SqlCommand command = new SqlCommand();
command.CommandText = "SP_SEARCH_USER";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@USERNAME", user_name);
//command.Connection = _connection;
string[] result;
result = new string[2];
result[0] = "0"; // предварительное зануление результатов для возвращения в случае ошибки
result[1] = "0";
List<string> formed_result_list = new List<string>(); //Вспомогательный список для формирования ответа
try
{
_connection.Open();
}
catch (Exception e)
{
Console.WriteLine("Ошибка: {0}", e.Message);
}
finally
{
try
{
SqlDataReader reader = command.ExecuteReader();
if(reader.HasRows) // если есть стороки
{
while (reader.Read())
{
formed_result_list.Add(reader.GetValue(0).ToString() + Configuration.znak_separator + reader.GetValue(1).ToString());
//Формируем ответ от хранимой процедуры в последовательность удобную для передачи по сети, в нашем случае значения столбцов разделяются & а записи в таблице разделяются |
}
}
_connection.Close();
result = new string[formed_result_list.Count];
for (int i = 0; i < result.Length; i++)
{
if (i == result.Length - 1)
{
result[i] = formed_result_list[i];
}
else
{
result[i] = formed_result_list[i] + Configuration.znak_separator_strok_from_bd;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return result; //Возвращение результата
}
public string SP_ADD_DIALOG_PARE(string id_user_from_client, string id_target_user) //добавление пользователя в БД возвращает 1 при успешном добавлении и 0 если такой пользователь существует
{
SqlCommand command = new SqlCommand();
command.CommandText = "SP_ADD_DIALOG_PARE";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@USER_ID_INICIATOR", id_user_from_client);
command.Parameters.AddWithValue("@USER_ID_DIALOG_START", id_target_user);
command.Connection = _connection;
string result = "0";
try
{
_connection.Open();
}
catch (Exception e)
{
Console.WriteLine("Ошибка: {0}", e.Message);
}
finally
{
try
{
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
while (reader.Read())
{
result = reader.GetValue(0).ToString();
}
_connection.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return result; //Возвращение результата
}
public string[] SP_SEARCH_DIALOG_PAIR(int user_id) //Вывод id и username всех пользователей с кем есть диалог
//id&username
//id&username
//id&username
//id&username
//id&username
{
SqlCommand command = new SqlCommand();
command.CommandText = "SP_SEARCH_DIALOG_PAIR";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@USER_ID_INICIATOR", user_id);
command.Connection = _connection;
string[] result;
result = new string[2]; // В случае отсутствия диалога с пользователем так как возвращает два столбца, вернет два пустых столбца
result[0] = "0";
result[1] = "0";
List<string> formed_result_list = new List<string>();
try
{
_connection.Open();
}
catch (Exception e)
{
Console.WriteLine("Ошибка: {0}", e.Message);
}
finally
{
try
{
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows) // если есть стороки
{
while (reader.Read())
{
formed_result_list.Add(reader.GetValue(0).ToString() + Configuration.znak_separator + reader.GetValue(1).ToString());
//Формируем ответ от хранимой процедуры в последовательность удобную для передачи по сети, в нашем случае значения столбцов разделяются & а записи в таблице разделяются |
}
}
_connection.Close();
result = new string[formed_result_list.Count];
for (int i = 0; i < result.Length; i++)
{
if (i == result.Length - 1)
{
result[i] = formed_result_list[i];
}
else
{
result[i] = formed_result_list[i] + Configuration.znak_separator_strok_from_bd;
}
}
command.Parameters.Clear(); // очистка параметров sql
command.Dispose();//Освобождаем все ресурсы SQL(Параметры)
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return result; //Возвращение результата
}
public bool connection_check()
{
try
{
_connection.Open();
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return false;
}
finally
{
_connection.Close();
}
}
}
}
Клиентская часть(С учетом передачи данных по сокетам):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Windows.Forms;
namespace WFChat
{
static class Network // класс для работы с сетью
{
static int port = Remote_Server_Network_config.SERVER_PORT;
static string address = Remote_Server_Network_config.SERVER_IP;
static TcpClient client = null;
static NetworkStream stream = null;
//----------------------------------------------------------------------------------------
public static void connect_initialization()
{
try
{
client = new TcpClient(Network.address, Network.port);
stream = client.GetStream();
}
catch (SocketException ex)
{
DialogResult res = MessageBox.Show("Ошибка подключения к серверу."+" Код ошибки: "+ex.ErrorCode+", Повторить подключение?", "Сервер недоступен!", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
if(res == DialogResult.Retry)
{
Network.connect_initialization();
}
if (res == DialogResult.Cancel)
{
Environment.Exit(1); // Завершение программы и передача ОС код завершения 1
}
}
}
//---------------------------------------------------------------------------------------
public static string[] Send_command_ret_str(string Tag, string Message,bool is_table)
/*
метод отправки сообщения(с упраляющими тэгами) на сервер
и получение ответа c большим буфером
Возвращает строковый массив, если сторона БД возвращает 1 элемент, то массив длинной 1
Если БД возвращает несколько элементов, то массив с таким количеством элементов
*/
{
string Tag_message = Tag_data_work.TagFormed(Tag, Message);
try
{
while (true)
{
// ввод сообщения
string message = Tag_message;
// преобразуем сообщение в массив байтов
byte[] data = Encoding.Unicode.GetBytes(message);
// отправка сообщения на сервер
stream.Write(data, 0, data.Length);
// получаем ответ от сервера (отработка хранимой процедуры)
//-------------------------------------------------------
if (is_table == false) //не таблица false
{
data = new byte[64]; // буфер для получаемых данных
StringBuilder builder = new StringBuilder();
int bytes = 0;
do
{
bytes = stream.Read(data, 0, data.Length);
builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
}
while (stream.DataAvailable);
//-------------------------------------------------------
if (builder.ToString().Contains(Remote_Server_Network_config.znak_separator))// Формирование массива при возвращении нескольких переменных
{
string[] server_answer = Tag_data_work.input_data_formed(builder.ToString());// ответ от сервера
return server_answer;// возвращение ответа
}
else // Формирование ответа при одной возвращаемой переменной
{
string[] server_answer = new string[1];
server_answer[0] = builder.ToString();
return server_answer;// возвращение ответа
}
}
if (is_table == true) // таблица
// ОТДЕЛЬНО ДЛЯ ТАБЛИЦ СДЕЛАНО НА БУДУЮШЕЕ ДЛЯ РЕАЛИЗАЦИИ ПЕРЕДАЧИ БОЛЬШИХ ТАБЛИЦ
{
data = new byte[64]; // буфер для получаемых данных
StringBuilder builder = new StringBuilder();
int bytes = 0;
do
{
bytes = stream.Read(data, 0, data.Length);
builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
}
while (stream.DataAvailable);
string[] server_answer = builder.ToString().Split(Remote_Server_Network_config.znak_separator_DB_table);
return server_answer;
// В случае возвращения табличных данных вернётся массив, элементом которого будет строка, данные столбцов которых будут разделены &
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
string[] error_answer = new string[1];
error_answer[0] = "0";
return error_answer;
}
}
}
}
Какие есть предположения, что в коде может быть не так при вызове хранимых процедур , что данные с одной процедуры переходят единоразово на вызов очередной?