Ayuda con T-SQL y C# (tratamiento de errores)
Publicado por William (3 intervenciones) el 17/10/2020 21:56:46
Hola, buenas tardes, soy nuevo con C# y T-SQL, quisiera pedirles una consulta que llevo días tratando de resolver y nada aún. Tengo instalado SQL Server 2017 y Visual Studio Enterprise 2019. tengo la siguiente situación:
Tengo en SQL Server creado la siguiente tabla:
También tengo el siguiente procedimiento almacenado:
Luego en C# tengo una clase llamada Datos que fue creada en el ficheros Datos.cs como se muestra a continuación:
Tengo además un formulario creado en el fichero Form3.cs con el siguiente método:
NOTA: lo que pretendo es lo siguiente:
1- Que el procedimiento almacenado devuelva en el parámetro @RESULT el número de error de división por cero.
2- El valor devuelto en ese parámetro asignárselo a la variable local "resultado" en el método Modificar de la clase Datos.
3- Devolver en el método Modificar de la clase Datos el valor de la variable "resultado".
4- Lanzar una excepción en el evento btnGuardar_Click con el número del error obtenido y un mensaje personalizado.
Alguien me puede ayudar. Al parecer nunca entra al bloque "catch (Exception exception1)", sino que pasa directamente al "Close();", al parecer pq en el sp nunca devuelve el valor del error en el parámetro @RESULT.
Tengo en SQL Server creado la siguiente tabla:
1
2
3
4
5
6
7
8
9
create table productos(
ID int primary key,
CATEGORIA varchar(30) not null,
MARCA varchar(30) not null,
MODELO varchar(30) not null,
CLASIFICACION varchar(30) not null,
SUBCLASIFICACION varchar(30) not null,
DESCRIPCION varchar(250) not null
);
También tengo el siguiente procedimiento almacenado:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ALTER PROCEDURE [dbo].[ModificarProducto]
@ID int,
@CATEGORIA varchar(30),
@MARCA varchar(30),
@MODELO varchar(30),
@CLASIFICACION varchar(30),
@SUBCLASIFICACION varchar(30),
@DESCRIPCION varchar(250),
@RESULT int output
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION
BEGIN TRY
select 1/0;
COMMIT TRANSACTION
END TRY
BEGIN CATCH
set @RESULT=ERROR_NUMBER();
IF (XACT_STATE()) = -1
ROLLBACK TRANSACTION;
IF (XACT_STATE()) = 1
COMMIT TRANSACTION
return @RESULT;
END CATCH
END
Luego en C# tengo una clase llamada Datos que fue creada en el ficheros Datos.cs como se muestra a continuación:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//Fichero Datos.cs
class Datos
{
private string CadenaConexion = "Data Source=SERVER; Initial Catalog=BD; Integrated Security=True";
private SqlConnection conn;
private DataTable dt;
public Datos()
{
this.conn = new SqlConnection(this.CadenaConexion);
}
public int Modificar(int id, string categoria, string marca, string modelo, string clasificacion, string subclasificacion, string descripcion)
{
int resultado=0;
dt = new DataTable();
string query = "ModificarProducto";
SqlCommand cmd = new SqlCommand(query, this.conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@ID", id));
cmd.Parameters.Add(new SqlParameter("@CATEGORIA", categoria));
cmd.Parameters.Add(new SqlParameter("@MARCA", marca));
cmd.Parameters.Add(new SqlParameter("@MODELO", modelo));
cmd.Parameters.Add(new SqlParameter("@CLASIFICACION", clasificacion));
cmd.Parameters.Add(new SqlParameter("@SUBCLASIFICACION", subclasificacion));
cmd.Parameters.Add(new SqlParameter("@DESCRIPCION", descripcion));
cmd.Parameters.Add(new SqlParameter("@RESULT", resultado));
SqlDataAdapter adap = new SqlDataAdapter(cmd);
adap.Fill(dt);
resultado = Convert.ToInt32(cmd.Parameters["@RESULT"].Value);
//MessageBox.Show(resultado.ToString());
conn.Close();
return resultado;
}
}
Tengo además un formulario creado en el fichero Form3.cs con el siguiente método:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//Fichero Form3.cs
private void btnGuardar_Click(object sender, EventArgs e)
{
int resultado = 0;
try
{
resultado = datos.Modificar(
System.Convert.ToInt32(txtId.Text),
txtCategoria.Text,
txtMarca.Text,
txtModelo.Text,
txtClasificacion.Text,
txtSubclasificacion.Text,
txtDescripcion.Text
);
if (resultado!=0)
throw new Exception("No se pudo modificar los datos");
}catch (Exception exception1) {
StringBuilder errorMessages = new StringBuilder();
errorMessages.Append(
"Número de error: " + resultado.ToString() + "\n"+
"Mensaje: " + exception1.Message + "\n"
);
MessageBox.Show(
errorMessages.ToString(),
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
Close();
}
NOTA: lo que pretendo es lo siguiente:
1- Que el procedimiento almacenado devuelva en el parámetro @RESULT el número de error de división por cero.
2- El valor devuelto en ese parámetro asignárselo a la variable local "resultado" en el método Modificar de la clase Datos.
3- Devolver en el método Modificar de la clase Datos el valor de la variable "resultado".
4- Lanzar una excepción en el evento btnGuardar_Click con el número del error obtenido y un mensaje personalizado.
Alguien me puede ayudar. Al parecer nunca entra al bloque "catch (Exception exception1)", sino que pasa directamente al "Close();", al parecer pq en el sp nunca devuelve el valor del error en el parámetro @RESULT.
Valora esta pregunta


0