Principales respuestas
Porcedimiento almacenado que devuelve datos

Pregunta
-
Amigos buenas tardes, tengo una tabla con muchas columnas , pero de esta solo necesito algunos campos cuando hago la selección , cree un strore procedure de selección y este lo cargo a un tableadapter en ado.net , pero cuando lanzo el evento este me desborda la app, hay alguna manera de que me pase a los controles de asp.net los campo que eh llamado en el select , espero me puedan ayudar ,este es el código que tengo
create proc SeleccionarCliente
@codclie varchar(50)
as
begin
select Descrip,TipoID,Direc1,Direc2,Pais,Estado,Ciudad,Municipio,Telef,Movil,Email,CodVend,CodConv,Observa,EsCredito from SACLIE where CodClie ='24318655'
enden C# lo llamo de esta manera
DsRemision.SACLIEDataTable cliente = CADCliente.ConsultaCliente(txtDocClie.Text);
foreach (DataRow row in cliente.Rows)
{
txtDocClie.Text = row["CodClie"].ToString();
txtDesClie.Text = row["Descrip"].ToString();
drpTDCliente.SelectedValue = row["TipoID"].ToString();
txtDirClie1.Text = row["Direc1"].ToString();
txtDirClien2.Text = row["Direc2"].ToString();
drpPais.SelectedValue = row["Pais"].ToString();
drpEstado.SelectedValue = row["Estado"].ToString();
drpCiudad.SelectedValue = row["Ciudad"].ToString();
drpMunicipio.SelectedValue = row["Municipio"].ToString();
txtTelClie.Text = row["Telef"].ToString();
txtcelClie.Text = row["Movil"].ToString();
txtEmailClie.Text = row["Email"].ToString();
drpVendedor.SelectedValue = row["CodVend"].ToString();
drpConClie.SelectedValue = row["CodConv"].ToString();
TextareaClie.InnerText = row["Observa"].ToString();
credito = Convert.ToInt32(row["EsCredito"].ToString());
if (credito == 1) { chboxcredito.Checked = true;}
else { chboxcredito.Checked = false; }
} lientScript.RegisterStartupScript(this.GetType(), "Mensaje", "<Script>swal" +
"('Cliente!', 'Consultado con exito!', 'success')</Script>");
Daniel
Respuestas
-
Hola Dannycv012:
Estás seguro de que llamas al procedure?
Cuantas rows te devuelve?
- Propuesto como respuesta Diana AcuñaModerator lunes, 27 de enero de 2020 22:12
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
no mme muestra nada de una me salta el siguiente error,"No se pudieron habilitar las restricciones. Una o varias filas contienen valores que infringen las restricciones NON-NULL, UNIQUE o FOREIGN-KEY."
este es el metodo en el que llamo el procedimiento almacenado
public static DsRemision.SACLIEDataTable ConsultaCliente(string codCliente)
{
return adapter.GetConsultarC(codCliente);
}Daniel
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
ese GetconsultarC es un Alias que le doy al procedimiento almacenado SeleccionarCliente
Daniel
- Editado Dannycv012 martes, 28 de enero de 2020 17:59
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
Hola Dannycv012:
La mejora manera de saber lo que ocurre es preguntarle a los participantes.
¿Y como le preguntamos al sql server? Para esto la opción más fácil, es utilizar el Sql Server Profiler.
Prepara la aplicación. Pon un punto de interrupción, antes de la llamada al procedure.
Arranca el Sql server profiler. Desde el Sql server managment Studio en el menú de herramientas. O desde Windows Microsoft Sql Server Tools
Conectate al servidor sql.
Cambia el selector hasta, Usar la plantilla en blanco, y pulsa en la siguiente pestaña, Selección de eventos.
Marca RPC Completed y ejecutar (esto no se puede hacer en producción porque genera un coste importante).
Ahora el profiler capturará las peticiones que le lleguen al sql server, para ejecutar tú procedure. Y verás las sentencias que se estan ejecutando.
Vuelves a visual studio donde tienes el código parado, y vas pulsando F11 ejecutando paso a paso, instrucción por instrucción, hasta ver la query que le manda tú código al sql server.
Yo tengo el punto de interrupción, justo antes de ejecutar conn.Open(); en este ejemplo de código.
Nada más que paso a ejecutar la sentencia var result= bd.ExecuteReader();, en el profiler veo la petición de ejecución que le hace mí código al procedure.
En la parte superior veo, la petición, con mucha informacíon, y en la parte de abajo, veo explicitamente la sentencia.
En este caso exec [dbo].[sp_acceso] @usuario=1
Esta es la sentencia que ejecuta mi código.
Creo que así puedes saber porque se vuelve loco. Algo no va a funcionar como tú crees.
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
javier muchas gracia s por este aporte , mira esto es lo que me arroja cuando corro el profile
Daniel
- Editado Dannycv012 miércoles, 29 de enero de 2020 13:55
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
Hola Daniel:
me devuelve la totalidad de las columnas en sql
En la primera parte de la pregunta, decías que tenías una tabla con muchas columnas, pero que el procedimiento solo recuperaba unas pocas.
¿Son las que te devuelve?
Por cierto tu procedure, tal cual lo has expresado no esta bien.
ALTER PROC SeleccionarCliente @codclie VARCHAR(50) AS BEGIN SELECT Descrip , TipoID , Direc1 , Direc2 , Pais , Estado , Ciudad , Municipio , Telef , Movil , Email , CodVend , CodConv , Observa , EsCredito FROM SACLIE WHERE CodClie = @codclie; END;
Observa que el Where te lo he cambiado por el parámetro recibido.
Luego tendrás que actualizar tu dataset.
Como en esta conversación.
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
Hola Dannycv012:
Empecemos por partes. Voy a crear la tabla en sql server y a insertar una fila (tu esto no lo haces porque ya lo tienes). Nota he puesto todas las columnas como varchar, pero era por facilidad. Pueden ser del tipo que realmente sean.
CREATE TABLE SACLIE ( CODCLIE VARCHAR(100) , DESCRIPCION VARCHAR(100) , TIPOID VARCHAR(100) , DIREC1 VARCHAR(100) , DIREC2 VARCHAR(100) , PAIS VARCHAR(100) , ESTADO VARCHAR(100) , CIUDAD VARCHAR(100) , MUNICIPIO VARCHAR(100) , TELEF VARCHAR(100) , MOVIL VARCHAR(100) , EMAIL VARCHAR(100) , CODVEND VARCHAR(100) , CODCONV VARCHAR(100) , OBSERVA VARCHAR(100) , ESCREDITO VARCHAR(100) ) GO INSERT INTO SACLIE (CODCLIE, DESCRIPCION,TIPOID, DIREC1, DIREC2, PAIS , ESTADO , CIUDAD, MUNICIPIO, TELEF , MOVIL , EMAIL , CODVEND, CODCONV, OBSERVA, ESCREDITO) VALUES ('24318655','DES','TIPO','DIRE','DIRE2','PAIS','ESTADO','CIUDAD','MUNICIPIO','TELEF','MOVIL','EMAIL','CONVEND','COD','OBSERVA','CREDITO'); GO
Ya tengo una tabla y una fila. Ahora voy a crear un procedure que me recupera una serie de columnas de la tabla.
CREATE PROC SeleccionarUnCliente @codclie VARCHAR(50) AS BEGIN SELECT TOP(1) CODCLIE , DESCRIPCION , TipoID , Direc1 , Direc2 , Pais , Estado , Ciudad , Municipio , Telef , Movil , Email , CodVend , CodConv , Observa , EsCredito FROM SACLIE WHERE CodClie = @codclie; END;
Fíjate que he llamado al procedimiento SeleccionarUnCliente y no seleccionar cliente, porque dentro he puesto el operador top, de manera que como mucho me devolverá una fila. Esto lo hago porque tú estas asignando el resultado a objetos textBox, por tanto solo esperas un resultado.
string user = "24318655"; string resultadoColumna1 = string.Empty; string constr = @"Persist Security Info=False;Integrated Security=true;Initial Catalog=Estudiantes;Server=ESQUINERO"; SqlConnection conn = new SqlConnection(constr); using (SqlConnection con = new SqlConnection(constr)) { SqlCommand bd = new SqlCommand("[dbo].[SeleccionarUnCliente]"); bd.CommandType = CommandType.StoredProcedure; conn.Open(); bd.Parameters.AddWithValue("@codClie", user); bd.Connection = conn; SqlDataReader reader = bd.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { resultadoColumna1 = reader.GetString(0); /// aqui tienes todos los datos Que en nuestro caso, serán todas las columnas y 1 sola fila por el operador top } } reader.Close(); }
Aquí ya hay algunas diferencias entre tú código y el mio.
Lo primero, obvio, que nuestra cadena de conexión la hemos puesto diferente.
Fíjate que he utilizado un bloque using para SqlConnection, así ocurra lo que ocurra no me tengo que preocupar de consumir close o dispose para liberar recursos, pues el bloque using lo hará por mi.
Siguiente paso, importante, el parámetro que quiere el procedimiento almacenado, yo solo le doy el parametro y el se encarga de la gestión. En tú caso ahora mismo, no cambia mucho, pero cuando trabajes con fechas, por ejemplo esto es muy importante, porque punto net se encargará de hablar con Sql en el formato que corresponda y no te generará problemas de conversión.
Además evita las inyecciones sql.
Luego he usado un SqlDataReader. Simplemente porque tú en la última ventana de código lo usas.
Fíjate que del datareader, leo si tiene filas, y si las tiene las recorro. Ya se que tiene una sola, pero el código es igual.
Del dataReader, puedes obtener las columnas con sus funciones GetString, GetInteger....etc.
A partír de ahi, tú mismo recupera los valores de las columnas y se los asignas a tus objetos (textBox y demás)
Recuperar datos con Datareader
https://docs.microsoft.com/es-es/dotnet/framework/data/adonet/retrieving-data-using-a-datareader
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
Todas las respuestas
-
Hola Dannycv012:
Estás seguro de que llamas al procedure?
Cuantas rows te devuelve?
- Propuesto como respuesta Diana AcuñaModerator lunes, 27 de enero de 2020 22:12
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
no mme muestra nada de una me salta el siguiente error,"No se pudieron habilitar las restricciones. Una o varias filas contienen valores que infringen las restricciones NON-NULL, UNIQUE o FOREIGN-KEY."
este es el metodo en el que llamo el procedimiento almacenado
public static DsRemision.SACLIEDataTable ConsultaCliente(string codCliente)
{
return adapter.GetConsultarC(codCliente);
}Daniel
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
Un procedimiento almacenado con una select, no parece lógico que te devuelva ese error.
Según tu primera anotación el procedimiento sql server se llama:
SeleccionarCliente y recibe un parámetro.
En ese GetConsultarC(codCliente) que código hay?
- Editado Javi Fernández F martes, 28 de enero de 2020 16:57
-
ese GetconsultarC es un Alias que le doy al procedimiento almacenado SeleccionarCliente
Daniel
- Editado Dannycv012 martes, 28 de enero de 2020 17:59
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
Hola Dannycv012:
La mejora manera de saber lo que ocurre es preguntarle a los participantes.
¿Y como le preguntamos al sql server? Para esto la opción más fácil, es utilizar el Sql Server Profiler.
Prepara la aplicación. Pon un punto de interrupción, antes de la llamada al procedure.
Arranca el Sql server profiler. Desde el Sql server managment Studio en el menú de herramientas. O desde Windows Microsoft Sql Server Tools
Conectate al servidor sql.
Cambia el selector hasta, Usar la plantilla en blanco, y pulsa en la siguiente pestaña, Selección de eventos.
Marca RPC Completed y ejecutar (esto no se puede hacer en producción porque genera un coste importante).
Ahora el profiler capturará las peticiones que le lleguen al sql server, para ejecutar tú procedure. Y verás las sentencias que se estan ejecutando.
Vuelves a visual studio donde tienes el código parado, y vas pulsando F11 ejecutando paso a paso, instrucción por instrucción, hasta ver la query que le manda tú código al sql server.
Yo tengo el punto de interrupción, justo antes de ejecutar conn.Open(); en este ejemplo de código.
Nada más que paso a ejecutar la sentencia var result= bd.ExecuteReader();, en el profiler veo la petición de ejecución que le hace mí código al procedure.
En la parte superior veo, la petición, con mucha informacíon, y en la parte de abajo, veo explicitamente la sentencia.
En este caso exec [dbo].[sp_acceso] @usuario=1
Esta es la sentencia que ejecuta mi código.
Creo que así puedes saber porque se vuelve loco. Algo no va a funcionar como tú crees.
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
javier muchas gracia s por este aporte , mira esto es lo que me arroja cuando corro el profile
Daniel
- Editado Dannycv012 miércoles, 29 de enero de 2020 13:55
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
-
-
-
me devuelve la totalidad de las columnas en sql , en el paso a paso en C# se detiene en el metodo que llama el procedimiento almacenado, en este paso se detiene
public static DsRemision.SACLIEDataTable ConsultaCliente(string codCliente)
{
return adapter.GetConsultarC(codCliente);
}Daniel
-
Hola Daniel:
me devuelve la totalidad de las columnas en sql
En la primera parte de la pregunta, decías que tenías una tabla con muchas columnas, pero que el procedimiento solo recuperaba unas pocas.
¿Son las que te devuelve?
Por cierto tu procedure, tal cual lo has expresado no esta bien.
ALTER PROC SeleccionarCliente @codclie VARCHAR(50) AS BEGIN SELECT Descrip , TipoID , Direc1 , Direc2 , Pais , Estado , Ciudad , Municipio , Telef , Movil , Email , CodVend , CodConv , Observa , EsCredito FROM SACLIE WHERE CodClie = @codclie; END;
Observa que el Where te lo he cambiado por el parámetro recibido.
Luego tendrás que actualizar tu dataset.
Como en esta conversación.
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
javier eh buscado otra forma y asi trata de traer los datos , pero no me muestra nada en los controles del formulario , soy novato aun en muchas cosas como podria cargar ahi mi procedimiento almacenado ,
var cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
var con = new SqlConnection(cs);
SqlDataAdapter da;
DataTable dt;
string id = txtDocClie.Text;
da = new SqlDataAdapter(" Select CodClie, Descrip,TipoID,Direc1," +
" Direc2,Pais,Estado,Ciudad,Municipio,Telef,Movil,Email,CodVend," +
" CodConv,Observa,EsCredito from SACLIE where CodClie ='"+id+"'", con);
dt = new DataTable();
da.Fill(dt);
txtDocClie.Text = dt.Rows[0][0].ToString();
txtDesClie.Text = dt.Rows[0][1].ToString();
drpTDCliente.SelectedValue = dt.Rows[0][2].ToString();
txtDirClie1.Text = dt.Rows[0][3].ToString();
txtDirClien2.Text = dt.Rows[0][4].ToString();
drpPais.SelectedValue = dt.Rows[0][5].ToString();
drpEstado.SelectedValue = dt.Rows[0][6].ToString();
drpCiudad.SelectedValue = dt.Rows[0][7].ToString();
drpMunicipio.SelectedValue = dt.Rows[0][8].ToString();
txtTelClie.Text = dt.Rows[0][9].ToString();
txtcelClie.Text = dt.Rows[0][10].ToString();
txtEmailClie.Text = dt.Rows[0][11].ToString();
drpVendedor.SelectedValue = dt.Rows[0][12].ToString();
drpConClie.SelectedValue = dt.Rows[0][13].ToString();
TextareaClie.InnerText = dt.Rows[0][14].ToString();
int credito = Convert.ToInt32(dt.Rows[0][15].ToString());
if (credito == 1) { chboxcredito.Checked = true; }
else { chboxcredito.Checked = false; }
return ;
}
Daniel
- Editado Dannycv012 miércoles, 29 de enero de 2020 21:11
-
Hola Dannycv012:
Empecemos por partes. Voy a crear la tabla en sql server y a insertar una fila (tu esto no lo haces porque ya lo tienes). Nota he puesto todas las columnas como varchar, pero era por facilidad. Pueden ser del tipo que realmente sean.
CREATE TABLE SACLIE ( CODCLIE VARCHAR(100) , DESCRIPCION VARCHAR(100) , TIPOID VARCHAR(100) , DIREC1 VARCHAR(100) , DIREC2 VARCHAR(100) , PAIS VARCHAR(100) , ESTADO VARCHAR(100) , CIUDAD VARCHAR(100) , MUNICIPIO VARCHAR(100) , TELEF VARCHAR(100) , MOVIL VARCHAR(100) , EMAIL VARCHAR(100) , CODVEND VARCHAR(100) , CODCONV VARCHAR(100) , OBSERVA VARCHAR(100) , ESCREDITO VARCHAR(100) ) GO INSERT INTO SACLIE (CODCLIE, DESCRIPCION,TIPOID, DIREC1, DIREC2, PAIS , ESTADO , CIUDAD, MUNICIPIO, TELEF , MOVIL , EMAIL , CODVEND, CODCONV, OBSERVA, ESCREDITO) VALUES ('24318655','DES','TIPO','DIRE','DIRE2','PAIS','ESTADO','CIUDAD','MUNICIPIO','TELEF','MOVIL','EMAIL','CONVEND','COD','OBSERVA','CREDITO'); GO
Ya tengo una tabla y una fila. Ahora voy a crear un procedure que me recupera una serie de columnas de la tabla.
CREATE PROC SeleccionarUnCliente @codclie VARCHAR(50) AS BEGIN SELECT TOP(1) CODCLIE , DESCRIPCION , TipoID , Direc1 , Direc2 , Pais , Estado , Ciudad , Municipio , Telef , Movil , Email , CodVend , CodConv , Observa , EsCredito FROM SACLIE WHERE CodClie = @codclie; END;
Fíjate que he llamado al procedimiento SeleccionarUnCliente y no seleccionar cliente, porque dentro he puesto el operador top, de manera que como mucho me devolverá una fila. Esto lo hago porque tú estas asignando el resultado a objetos textBox, por tanto solo esperas un resultado.
string user = "24318655"; string resultadoColumna1 = string.Empty; string constr = @"Persist Security Info=False;Integrated Security=true;Initial Catalog=Estudiantes;Server=ESQUINERO"; SqlConnection conn = new SqlConnection(constr); using (SqlConnection con = new SqlConnection(constr)) { SqlCommand bd = new SqlCommand("[dbo].[SeleccionarUnCliente]"); bd.CommandType = CommandType.StoredProcedure; conn.Open(); bd.Parameters.AddWithValue("@codClie", user); bd.Connection = conn; SqlDataReader reader = bd.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { resultadoColumna1 = reader.GetString(0); /// aqui tienes todos los datos Que en nuestro caso, serán todas las columnas y 1 sola fila por el operador top } } reader.Close(); }
Aquí ya hay algunas diferencias entre tú código y el mio.
Lo primero, obvio, que nuestra cadena de conexión la hemos puesto diferente.
Fíjate que he utilizado un bloque using para SqlConnection, así ocurra lo que ocurra no me tengo que preocupar de consumir close o dispose para liberar recursos, pues el bloque using lo hará por mi.
Siguiente paso, importante, el parámetro que quiere el procedimiento almacenado, yo solo le doy el parametro y el se encarga de la gestión. En tú caso ahora mismo, no cambia mucho, pero cuando trabajes con fechas, por ejemplo esto es muy importante, porque punto net se encargará de hablar con Sql en el formato que corresponda y no te generará problemas de conversión.
Además evita las inyecciones sql.
Luego he usado un SqlDataReader. Simplemente porque tú en la última ventana de código lo usas.
Fíjate que del datareader, leo si tiene filas, y si las tiene las recorro. Ya se que tiene una sola, pero el código es igual.
Del dataReader, puedes obtener las columnas con sus funciones GetString, GetInteger....etc.
A partír de ahi, tú mismo recupera los valores de las columnas y se los asignas a tus objetos (textBox y demás)
Recuperar datos con Datareader
https://docs.microsoft.com/es-es/dotnet/framework/data/adonet/retrieving-data-using-a-datareader
- Marcado como respuesta Pablo RubioModerator jueves, 30 de enero de 2020 17:43
-
Javier muchas gracias por tu ayuda me han servido tus consejos para aprender cosas nuevas , lo ultimo que me enviaste funciona muy bien , realice el seguimiento con profile y corre excelente , pero no me logra traer los datos a los controles textbox ya estoy mirando si el error esta en el codebin en c#
Daniel
- Editado Dannycv012 jueves, 30 de enero de 2020 15:41