Re: Отображение сообщения хранимой процедуры в окне приложения C#
От: Olaf Россия  
Дата: 06.04.14 10:48
Оценка: +1
Здравствуйте, peacelennon, Вы писали:

P>Здравствуйте! у меня ив БД (Sql Server 2012) имеется такая процедура:

P>...
P>Она добавляет новый товар в таблицу. В ней есть проверка на существующий товар,если я добавляю существ товар,выводится сообщение "Есть такой товар!".Так вот,т.к. я работаю с этой БД в приложении на C#, я вызываю там эту процедуру т.о.:
P>...
P>Все работает,все ок, существ товар не добавляет, НО не выводит сообщение "Есть такой товар!" .Как это сделать? Заранее спасибо.

Как правильно заметили выше, вашу идею для отлова print можно реализовать через SqlConnection.InfoMessage
SqlConnection connection = new SqlConnection("…");
 
connection.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageEventHandler);
...    
 
static void InfoMessageEventHandler(object sender, SqlInfoMessageEventArgs e)
{
    string message = e.Message;            
}


Существуют однако и другие варианты возврата сообщений и управления в клиентское приложение.
1. Добавить в ХП output parameter и заполнять его в процедуре
create procedure dbo.usp_Test(…., @msg varchar(100) output) as

if exists(…)
    set @msg = 'Есть такой товар!'
else
    insert …
go


Код на C#
  Скрытый текст
using (SqlConnection connection = new SqlConnection("..."))
{
    SqlCommand command = new SqlCommand();
    command.CommandText = "dbo.usp_Test";
    command.Connection = connection;
    command.CommandType = System.Data.CommandType.StoredProcedure;

    SqlParameter param1 = command.CreateParameter();
    param1.ParameterName = "@param1";
    param1.Value = "Значение 1";

    SqlParameter param2 = command.CreateParameter();
    param2.ParameterName = "@param2";
    param2.Value = "Значение 2";

    SqlParameter msg = command.CreateParameter();
    msg.ParameterName = "@msg";
    msg.DbType = System.Data.DbType.String;
    msg.Size = 100;
    msg.Direction = System.Data.ParameterDirection.Output;

    command.Parameters.Add(param1);
    command.Parameters.Add(param2);
    command.Parameters.Add(msg);

    connection.Open();

    command.ExecuteNonQuery();

    if (!string.IsNullOrEmpty(msg.Value.ToString()))
    {
        string message = msg.Value.ToString();
    }
}


2. Возвращать код ошибки из ХП, после чего на клиенте обрабатывать и генерировать сообщение
create procedure dbo.usp_Test(….) as

if exists(…)
    return 50001
else
    insert …
go


Код на C#
  Скрытый текст
using (SqlConnection connection = new SqlConnection(@"…"))
{
    SqlCommand command = new SqlCommand();
    command.CommandText = "dbo.usp_Test";
    command.Connection = connection;
    command.CommandType = System.Data.CommandType.StoredProcedure;

    SqlParameter param1 = command.CreateParameter();
    param1.ParameterName = "@param1";
    param1.Value = "Значение 1";

    SqlParameter param2 = command.CreateParameter();
    param2.ParameterName = "@param2";
    param2.Value = "Значение 2";

    SqlParameter returnValue = new SqlParameter();
    returnValue.Direction = System.Data.ParameterDirection.ReturnValue;

    command.Parameters.Add(param1);
    command.Parameters.Add(param2);
    command.Parameters.Add(returnValue);

    connection.Open();

    command.ExecuteNonQuery();

    if ((int)returnValue.Value == 50001)
    {
        string message = "Такой товар уже есть!";
    }
}


3. Генерировать ошибку в ХП и отлавливать на клиенте, предварительно создав на сервере соответствующее сообщение через
EXEC sp_addmessage 50002, 16, N'Такой товар уже есть!'


create procedure dbo.usp_Test(….) as

if exists(…)
    raiseerror(50002, 16, 1)
else
    insert …
go


Код на C#
  Скрытый текст
try
{
    using (SqlConnection connection = new SqlConnection("…"))
    {
        SqlCommand command = new SqlCommand();
        command.CommandText = "dbo.usp_Test";
        command.Connection = connection;
        command.CommandType = System.Data.CommandType.StoredProcedure;

        SqlParameter param1 = command.CreateParameter();
        param1.ParameterName = "@param1";
        param1.Value = "Значение 1";

        SqlParameter param2 = command.CreateParameter();
        param2.ParameterName = "@param2";
        param2.Value = "Значение 2";

        command.Parameters.Add(param1);
        command.Parameters.Add(param2);
        connection.Open();

        command.ExecuteNonQuery();
    }
}
catch (SqlException ex)
{
    if (ex.Number == 50002)
    {
        string message = "Такой товар уже есть!";
    }
    else throw;
}


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

create procedure dbo.usp_Test(….) as

if not exists(…)
    insert 

go


Код на C#
  Скрытый текст
using (SqlConnection connection = new SqlConnection("..."))
{
    SqlCommand command = new SqlCommand();
    command.CommandText = "dbo.usp_Test";
    command.Connection = connection;
    command.CommandType = System.Data.CommandType.StoredProcedure;

    SqlParameter param1 = command.CreateParameter();
    param1.ParameterName = "@param1";
    param1.Value = "Значение 1";

    SqlParameter param2 = command.CreateParameter();
    param2.ParameterName = "@param2";
    param2.Value = "Значение 2";

    command.Parameters.Add(param1);
    command.Parameters.Add(param2);

    connection.Open();

    int i = command.ExecuteNonQuery();
    if (i != 1)
    {
        string message = "Такой товар уже есть!";
    }
}

P.S. Я бы все-таки использовали встроенные возможности ADO.Net в частности Command и параметры, вместо генерации запроса на лету из данных, которые пользователь ввел в форме.
Отображение сообщения хранимой процедуры в окне приложения C#
От: peacelennon  
Дата: 05.04.14 16:22
Оценка:
Здравствуйте! у меня ив БД (Sql Server 2012) имеется такая процедура:



[sql]
create procedure ADD_tovar_Catalog (@name_tovara nvarchar(50),
@id_firmy int, @id_categ int, @volume int, @ed_izmer nvarchar(30) ,
@colour nvarchar(30), @recommend nvarchar(max))
as
 BEGIN 

 IF EXISTS (SELECT [Наименование товара], ID_фирмы, ID_категории, Объем, [Единица измерения], Цвет,
 Рекомендация

  FROM Каталог WHERE [Наименование товара] = @name_tovara and ID_фирмы = @id_firmy and
  ID_категории = @id_categ and Объем = @volume and [Единица измерения] = @ed_izmer and 
  Цвет = @colour and Рекомендация = @recommend)
         BEGIN
            print 'Есть такой товар!'
         END
    ELSE
         BEGIN 

             INSERT INTO Каталог ([Наименование товара], [ID_фирмы], 
[ID_категории], [Объем], [Единица измерения], [Цвет], [Рекомендация])
             VALUES (@name_tovara, @id_firmy, @id_categ, 
             @volume, @ed_izmer, @colour, @recommend)
         END
         end
[/sql]



Она добавляет новый товар в таблицу. В ней есть проверка на существующий товар,если я добавляю существ товар,выводится сообщение "Есть такой товар!".Так вот,т.к. я работаю с этой БД в приложении на C#, я вызываю там эту процедуру т.о.:



[c#]
private void button1_Click(object sender, EventArgs e)
        {
            try
           {
                SqlConnection conn1 = new SqlConnection(@"Data Source=(LocalDB)\v11.0;
            AttachDbFilename=C:\Program Files\World Cosmetics\Мир косметики.mdf;
            Integrated Security=True;Connect Timeout=30");
                DataSet data_set = new DataSet();
                string zapros = string.Empty;
                zapros = " exec ADD_tovar_Catalog  " + "'" + textBox2.Text + "'" + ","
                     + textBox4.Text + "," + textBox5.Text + "," + textBox6.Text + "," + "'" + textBox7.Text +
                    "'" + "," + "'" + textBox8.Text + "'" + "," + "'" + textBox9.Text + "'";
                SqlDataAdapter data_adapter = new SqlDataAdapter(zapros, conn1);
                data_adapter.Fill(data_set);
               
 
            }
            

          catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
[/c#]



Все работает,все ок, существ товар не добавляет, НО не выводит сообщение "Есть такой товар!" .Как это сделать? Заранее спасибо.
c# sql
Re: Отображение сообщения хранимой процедуры в окне приложения C#
От: _Raz_  
Дата: 05.04.14 16:41
Оценка:
Здравствуйте, peacelennon, Вы писали:

P>Все работает,все ок, существ товар не добавляет, НО не выводит сообщение "Есть такой товар!" .Как это сделать? Заранее спасибо.


THROW (Transact-SQL)
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 77>>
Re: Отображение сообщения хранимой процедуры в окне приложения C#
От: maloi_alex СССР  
Дата: 05.04.14 18:26
Оценка:
Здравствуйте, peacelennon, Вы писали:

SqlConnection.InfoMessage
Re: Отображение сообщения хранимой процедуры в окне приложения C#
От: peacelennon  
Дата: 06.04.14 13:44
Оценка:
Спасибо всем большое! Но я уже вчера додумалась всё-таки сделать ошибку raiseerror и отловила ее try-catch и все показало.Спасибо.В дальнейшем ваша информация мне будет полезна)
Re[2]: Отображение сообщения хранимой процедуры в окне приложения C#
От: Аноним  
Дата: 26.04.14 10:49
Оценка:
Здравствуйте, Olaf, Вы писали:

O>Здравствуйте, peacelennon, Вы писали:


P>>Здравствуйте! у меня ив БД (Sql Server 2012) имеется такая процедура:

P>>...
P>>Она добавляет новый товар в таблицу. В ней есть проверка на существующий товар,если я добавляю существ товар,выводится сообщение "Есть такой товар!".Так вот,т.к. я работаю с этой БД в приложении на C#, я вызываю там эту процедуру т.о.:
P>>...
P>>Все работает,все ок, существ товар не добавляет, НО не выводит сообщение "Есть такой товар!" .Как это сделать? Заранее спасибо.

O>Как правильно заметили выше, вашу идею для отлова print можно реализовать через SqlConnection.InfoMessage

O>
O>SqlConnection connection = new SqlConnection("…");
 
O>connection.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageEventHandler);
O>...    
 
O>static void InfoMessageEventHandler(object sender, SqlInfoMessageEventArgs e)
O>{
O>    string message = e.Message;            
O>}
O>


O>Существуют однако и другие варианты возврата сообщений и управления в клиентское приложение.

O>1. Добавить в ХП output parameter и заполнять его в процедуре
O>
O>create procedure dbo.usp_Test(…., @msg varchar(100) output) as

O>if exists(…)
O>    set @msg = 'Есть такой товар!'
O>else
O>    insert …
O>go
O>


O>Код на C#

O>
  Скрытый текст
O>
O>using (SqlConnection connection = new SqlConnection("..."))
O>{
O>    SqlCommand command = new SqlCommand();
O>    command.CommandText = "dbo.usp_Test";
O>    command.Connection = connection;
O>    command.CommandType = System.Data.CommandType.StoredProcedure;

O>    SqlParameter param1 = command.CreateParameter();
O>    param1.ParameterName = "@param1";
O>    param1.Value = "Значение 1";

O>    SqlParameter param2 = command.CreateParameter();
O>    param2.ParameterName = "@param2";
O>    param2.Value = "Значение 2";

O>    SqlParameter msg = command.CreateParameter();
O>    msg.ParameterName = "@msg";
O>    msg.DbType = System.Data.DbType.String;
O>    msg.Size = 100;
O>    msg.Direction = System.Data.ParameterDirection.Output;

O>    command.Parameters.Add(param1);
O>    command.Parameters.Add(param2);
O>    command.Parameters.Add(msg);

O>    connection.Open();

O>    command.ExecuteNonQuery();

O>    if (!string.IsNullOrEmpty(msg.Value.ToString()))
O>    {
O>        string message = msg.Value.ToString();
O>    }
O>}
O>



O>2. Возвращать код ошибки из ХП, после чего на клиенте обрабатывать и генерировать сообщение

O>
O>create procedure dbo.usp_Test(….) as

O>if exists(…)
O>    return 50001
O>else
O>    insert …
O>go
O>


O>Код на C#

O>
  Скрытый текст
O>
O>using (SqlConnection connection = new SqlConnection(@"…"))
O>{
O>    SqlCommand command = new SqlCommand();
O>    command.CommandText = "dbo.usp_Test";
O>    command.Connection = connection;
O>    command.CommandType = System.Data.CommandType.StoredProcedure;

O>    SqlParameter param1 = command.CreateParameter();
O>    param1.ParameterName = "@param1";
O>    param1.Value = "Значение 1";

O>    SqlParameter param2 = command.CreateParameter();
O>    param2.ParameterName = "@param2";
O>    param2.Value = "Значение 2";

O>    SqlParameter returnValue = new SqlParameter();
O>    returnValue.Direction = System.Data.ParameterDirection.ReturnValue;

O>    command.Parameters.Add(param1);
O>    command.Parameters.Add(param2);
O>    command.Parameters.Add(returnValue);

O>    connection.Open();

O>    command.ExecuteNonQuery();

O>    if ((int)returnValue.Value == 50001)
O>    {
O>        string message = "Такой товар уже есть!";
O>    }
O>}
O>



O>3. Генерировать ошибку в ХП и отлавливать на клиенте, предварительно создав на сервере соответствующее сообщение через

O>
O>EXEC sp_addmessage 50002, 16, N'Такой товар уже есть!'
O>


O>
O>create procedure dbo.usp_Test(….) as

O>if exists(…)
O>    raiseerror(50002, 16, 1)
O>else
O>    insert …
O>go

O>


O>Код на C#

O>
  Скрытый текст
O>
O>try
O>{
O>    using (SqlConnection connection = new SqlConnection("…"))
O>    {
O>        SqlCommand command = new SqlCommand();
O>        command.CommandText = "dbo.usp_Test";
O>        command.Connection = connection;
O>        command.CommandType = System.Data.CommandType.StoredProcedure;

O>        SqlParameter param1 = command.CreateParameter();
O>        param1.ParameterName = "@param1";
O>        param1.Value = "Значение 1";

O>        SqlParameter param2 = command.CreateParameter();
O>        param2.ParameterName = "@param2";
O>        param2.Value = "Значение 2";

O>        command.Parameters.Add(param1);
O>        command.Parameters.Add(param2);
O>        connection.Open();

O>        command.ExecuteNonQuery();
O>    }
O>}
O>catch (SqlException ex)
O>{
O>    if (ex.Number == 50002)
O>    {
O>        string message = "Такой товар уже есть!";
O>    }
O>    else throw;
O>}
O>



O>4. Использовать встроенную возможность ExecuteNonQuery, возвращать количество модифицированных записей при использовании DML


O>
O>create procedure dbo.usp_Test(….) as

O>if not exists(…)
O>    insert 

O>go
O>


O>Код на C#

O>
  Скрытый текст
O>
O>using (SqlConnection connection = new SqlConnection("..."))
O>{
O>    SqlCommand command = new SqlCommand();
O>    command.CommandText = "dbo.usp_Test";
O>    command.Connection = connection;
O>    command.CommandType = System.Data.CommandType.StoredProcedure;

O>    SqlParameter param1 = command.CreateParameter();
O>    param1.ParameterName = "@param1";
O>    param1.Value = "Значение 1";

O>    SqlParameter param2 = command.CreateParameter();
O>    param2.ParameterName = "@param2";
O>    param2.Value = "Значение 2";

O>    command.Parameters.Add(param1);
O>    command.Parameters.Add(param2);

O>    connection.Open();

O>    int i = command.ExecuteNonQuery();
O>    if (i != 1)
O>    {
O>        string message = "Такой товар уже есть!";
O>    }
O>}
O>


O>P.S. Я бы все-таки использовали встроенные возможности ADO.Net в частности Command и параметры, вместо генерации запроса на лету из данных, которые пользователь ввел в форме.

Кремень!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.