none
Generador de Código Alfanumérico con ASP.NET C# Y SQL RRS feed

  • Pregunta

  • Buenos Dias <o:p></o:p>

    necesito de sus ayudas estoy creando un aplicativo el cual debe generar un código automático alfanúmero <o:p></o:p>

    he realizado esta consulta, pero me puesta error necesito que me ayudan la mejor formar de hacerlo y poder tenerlo lo ideal es que sea alfanúmero NCL y luego el numero consecutivo mantengo dos tablas una que se llama cliente la cual mostrar el código y otra llamada Gcodigo que es la que tendrá la operación le dejo el código para que me ayuden y existe la forma de hacerlo con un procedimiento almacenado sería mejor soy principiante es esto y es mi proyecto de la universidad <o:p></o:p>

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    using System.Data;
    using System.Data.SqlClient;

    namespace CapaLogicaNegocio.BL
    {
        public class clsGCodigoCliente
        {
            SqlConnection _SqlConnection = null;//me permite establecer comunicacion con bbdd
            SqlCommand _sqlCommand = null; // me permite ejecutar comandos SQL
            SqlDataAdapter _sqlDataAdapter = null; //me permite adaptar conjuntod de datos SQL
            string stConexion = string.Empty;//cadena de conexion 

            SqlParameter sqlParameter = null;

            public clsGCodigoCliente()
            {
                ClsConexion obclsConexion = new ClsConexion();
                stConexion = obclsConexion.getConexion();
            }

            //VALIDAR USUARIO
            public string GeneradorCodigo(string nomtabla)
            {
                SqlConnection cn = instacia.CadenaConexion();
                string resultado = "";
                int ceros = 0;
                string Codigo = "";
                DataSet ds = new DataSet();
                SqlDataAdapter consulta = new SqlDataAdapter("select NUMERO from GCodigoCliente where NombTabla='" + nomtabla + "'", cn);
                ds.Reset();
                consulta.Fill(ds, "GCodigoCliente");
                if(ds.Tables["GCodigoCliente"].Rows.Count > 0)
                {
                    resultado = ds.Tables["GCodigoCliente"].Rows[0][0] + 1.ToString().Trim();
                    ceros = 4 - resultado.Length;
                    switch (ceros)
                    {
                        case 0:
                            Codigo = "NCL0000" + resultado;
                            break;
                        case 1:
                            Codigo = "NCL000" + resultado;
                            break;
                        case 2:
                            Codigo = "NCL00" + resultado;
                            break;
                        case 3:
                            Codigo = "NCL0" + resultado;
                            break;
                    }
                }
                else
                {

                }
                return Codigo;
            }
        }
    }


    • Editado jstin11 jueves, 14 de febrero de 2019 18:50 Titulo mal escrito
    jueves, 14 de febrero de 2019 18:44

Respuestas

  • Hola:

    Si ya tienes el procedure, tendrás que cambiar create por alter

    CREATE PROCEDURE SP_CODIGO_CLIENTE
    AS
        BEGIN
    		DECLARE @CADENA AS VARCHAR(10);
    		SET @CADENA = 'NCL';
            DECLARE @num INT;
            SET @num =
            (
                SELECT ISNULL(MAX(numero), 0) + 1
                FROM cliente
            );
    
    
            SELECT @CADENA + RIGHT(CAST((POWER(10, 4) + @NUM) AS VARCHAR(5)), 4);
    
            RETURN;
        END;
    
    

    Si lo ejecutas directamente te devolverá

    NCLXXXX, donde XXXX es el máximo cliente más 1

    • Marcado como respuesta jstin11 martes, 19 de febrero de 2019 0:48
    lunes, 18 de febrero de 2019 5:18

Todas las respuestas

  • Hola jstin11

    Gracias por subir tu consulta a foros de MSDN, te comparto un URL ue creo te puede ayudar a solucionar tu problema, de no ser asi estaremos realizando una busqueda más exhaustiva al respecto.

    https://www.lawebdelprogramador.com/foros/Visual-Basic.NET/1031095-generador-de-contrasenas-alfanumericas.html

    jueves, 14 de febrero de 2019 22:39
    Moderador
  • Hola jstin11:

    Te voy a exponer un ejemplo de como lo puedes hacer con un procedure. No entiendo muy bien lo de las dos tablas, supongo que te refieres, a que querrías utilizar el mismo procedure por las dos tablas, pero no me parece el camino más correcto, ya que en SQL Server, tendrías que lidiar con una consulta dinámica. (Es fácil, pero tiene sus peligros).

    El primer problema, que tiene esto, es que no es válido para bases de datos con alta concurrencia. Tienes que tener en cuenta que si usas ese código, otro programa podría obtener el mismo código y grabar datos repetidos. Si no es el caso, entonces el ejemplo es válido.

    CREATE TABLE cliente
    (numero INT
     PRIMARY KEY, 
     nombre VARCHAR(100)
    );
    GO
    INSERT INTO cliente
    (numero, 
     nombre
    )
    VALUES
    (1, 
     'Ana'
    ),
    (2, 
     'Lucas'
    );
    GO
    CREATE PROCEDURE SP_CODIGO_CLIENTE(@CADENA AS VARCHAR(10))
    AS
        BEGIN
            DECLARE @num INT;
            SET @num =
            (
                SELECT ISNULL(MAX(numero), 0) + 1
                FROM cliente
            );
    
            /* INTRODUCIMOS EL CODIGO DEL CLIENTE EN LA VARIABLE @NUM*/
    
            SELECT @CADENA + RIGHT(CAST((POWER(10, 4) + @NUM) AS VARCHAR(5)), 4);
    
            /*DEVOLVEMOS LA CADENA*/
    
            RETURN;
        END;
    
    
    

    Con la estrutura de una tabla creada y su procedimiento (observa que le paso como parámetro una cadena, para poder reutilizarlo, por si mañana no es NCL sino NCLA...o B)

     public string Codigo_Cliente()
            {
                string resultado = "";
                SqlConnection sqlcon = new SqlConnection();
    
                var ConnectionString = @"Data Source = ESQUINERO; Initial Catalog = ejTres; Integrated Security = True";
    
                using (SqlConnection conn = new SqlConnection(ConnectionString))
                {
                    SqlCommand SqlCmd = new SqlCommand("SP_CODIGO_CLIENTE", conn);
                    SqlCmd.CommandType = CommandType.StoredProcedure;
                    try
                    {
                        SqlCmd.Parameters.AddWithValue("@CADENA", "NCL");
                        conn.Open();
                        resultado = (string)SqlCmd.ExecuteScalar() ;
                    }
                    catch (Exception ex)
                    {
                        //loguear el error
                    }
    
                    return resultado;
                }
            }

    Con esto puedes recuperar tu código.

    Una opción factible, es que tu método generadorDeCodigo(nomTabla), tuviera un swich,y en función de la tabla recibida, llamase a un método privado, como el que te expongo, para cada tabla.

    Bueno hay muchas maneras de orientarlo.

    Espero te ayude

    viernes, 15 de febrero de 2019 5:52
  • Buenas no entendido ando enredado y gracias de ante manos, necesito ayuda estoy terminando un trabajo de examen de la universidad, pero estoy enredado y necesito realizar un sistema de gestión de clientes web en aspx net C# con base de dato sqlserver, al presionar el botón de nuevo cliente se debe cargar un textbox con el ID generado alfanumérico desde SQL Server ejemplo NCL0001, NCL0002 etc. El proyecto lo estoy realizando en capas adjunto imagen no entiendo muy bien cómo realizarel generador de código, si me pueden ayudar con un procedimiento almacenado o como realizarlo y que me aparezca al momento de ejecutar el aplicativo es de mucha urgencia para mí por favor agéndenme 

    lunes, 18 de febrero de 2019 1:40
  • Hola:

    Si ya tienes el procedure, tendrás que cambiar create por alter

    CREATE PROCEDURE SP_CODIGO_CLIENTE
    AS
        BEGIN
    		DECLARE @CADENA AS VARCHAR(10);
    		SET @CADENA = 'NCL';
            DECLARE @num INT;
            SET @num =
            (
                SELECT ISNULL(MAX(numero), 0) + 1
                FROM cliente
            );
    
    
            SELECT @CADENA + RIGHT(CAST((POWER(10, 4) + @NUM) AS VARCHAR(5)), 4);
    
            RETURN;
        END;
    
    

    Si lo ejecutas directamente te devolverá

    NCLXXXX, donde XXXX es el máximo cliente más 1

    • Marcado como respuesta jstin11 martes, 19 de febrero de 2019 0:48
    lunes, 18 de febrero de 2019 5:18
  • Hola Sr Javi me puede indicar que significa @cadena y @num 
    martes, 19 de febrero de 2019 1:20
  • Estoy tratando de implementar lo que me dijo el procedimiento almacenado lo hice de la siguiente manera

    CREATE PROCEDURE SPCODIGOCLIENTE

    AS

        BEGIN

                  DECLARE @CADENA AS VARCHAR(10);

                  SET @CADENA = 'NCL';

            DECLARE @num INT;

            SET @num =

            (

                SELECT ISNULL(MAX(IDNCliente), 0) + 1

                FROM Cliente

            );

            SELECT @CADENA + RIGHT(CAST((POWER(10, 4) + @NUM) AS VARCHAR(5)), 4);

            RETURN;

        END;

     

    Pero no me sale nada en el textbox cuando cargo la página por favor me ayuda, ya he realizado las consultas desde la base de datos de guardar, actualizar y borrar datos.

    Usted me disculpa por todo, pero soy un estudiante principiante queriendo aprender y poder realizar mi trabajo universitario, le cuento mantengo un proyecto en capas de la siguiente manera en la solución de capa lógica, he creado en la carpeta BL la clase de clsCodGenerador con la siguiente formula 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    using System.Data;
    using System.Data.SqlClient;

    namespace CapaLogicaNegocio.BL
    {
        public class clsCodGenerador
        {
            SqlConnection _SqlConnection = null;//me permite establecer comunicacion con bbdd
            SqlCommand _sqlCommand = null; // me permite ejecutar comandos SQL
            SqlDataAdapter _sqlDataAdapter = null; //me permite adaptar conjuntod de datos SQL
            string stConexion = string.Empty;//cadena de conexion 

            SqlParameter sqlParameter = null;

            public clsCodGenerador()
            {
                ClsConexion obclsConexion = new ClsConexion();
                stConexion = obclsConexion.getConexion();
            }

            //VALIDAR USUARIO
            public DataSet getCodGenerador()
            {
                try
                {
                    DataSet dsConsulta = new DataSet();

                    _SqlConnection = new SqlConnection(stConexion);
                    _SqlConnection.Open();

                    _sqlCommand = new SqlCommand("SPCODIGOCLIENTE", _SqlConnection);
                    _sqlCommand.CommandType = CommandType.StoredProcedure;

                    _sqlCommand.ExecuteNonQuery();

                    _sqlDataAdapter = new SqlDataAdapter(_sqlCommand);
                    _sqlDataAdapter.Fill(dsConsulta);

                    return dsConsulta;

                }
                catch (Exception ex) { throw ex; }
                finally { _SqlConnection.Close(); }

            }
        }
    }


    En la carpeta models tengo la siguiente clase clsCodGenerador

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace CapaLogicaNegocio.Models
    {
       public class clsCodGenerador
        {
            public int inIDNCliente { get; set; }

        }
    }


    En la capa presentación en la clase de vista aspx tengo lo siguiente 

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    using System.Data.SqlClient;
    using CapaLogicaNegocio;

    namespace CapaPresentacion.Views
    {
        public partial class NCliente : System.Web.UI.Page
        {
            public void Limpiar()
            { //Generador de Codigo
                TextNCliente.Text = "";

            }
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)

    DataSet dsCodGenerador = obNCliente.getCodGenerador();

    DDRCCobro.DataSource = dsCodGenerador;
                    DDRCCobro.DataTextField = "IDNCliente"; //lo que se muestra

    Por favor me ayuda con eso a ver si me corrige esto no tengo idea de cómo generar eso lo estoy haciendo de esta manera tomando un ejemplo del cual realice las cargas de información de un DropDownList.

    Mantengo la siguiente arquitectura una solución de proyecto en capas, la capa negoción contiene dos carpetas una de BL y la otra de Models, Luego mantengo otra capa presentación que contiene dos carpetas controller y la otra vista

    necesita de sus ayudas por favor y gracias 

     

    Saludos 


    martes, 19 de febrero de 2019 2:33
  • Hola jstin11:

    ¿No puedes trazar para saber si te conecta correctamente?

    DataSet dsCodGenerador = obNCliente.getCodGenerador();

    No veo que hayas llamado al constructor de obNCliente, no se si existe el objeto y por tanto la conexión a la bbdd es correcta.

    https://docs.microsoft.com/es-es/visualstudio/debugger/using-breakpoints?view=vs-2017


    martes, 19 de febrero de 2019 5:28
  • Hola Javi me puedes ayudar con el procedimiento almacenado que me indicas que seria @CADENA y @num para poder realializar el procedimiento y como lo puedo armas en el visual c#

          

          

    viernes, 22 de febrero de 2019 1:06
  • Hola Codigo Alfanumérico con ASPNET C Y sqlserve

    Lo primero, es que intentaré ayudarte todo lo que pueda. Si pongo algo o me lo salto, o no esta claro o ....sin miedo.

    Te voy a explicar como he puesto el código del procedimiento, que vaya por delante que se puede refactorizar a una sola linea, pero creía que sería mucho más didáctico así:

    Create PROCEDURE SP_CODIGOCLIENTE

    En Sql Server cuando un procedimiento esta creado, si ya lo tienes hay que cambiar Create por Alter.

    Declare @cadena as Varchar(10); -->Esto es una declaración de una variable temporal que dura el contexto de uso del procedure.

    Set @cadena = 'NCL' -->le asigno a la cadena ese valor literal.

    Declare @num int; -->declaración de variable temporal tipo integer.

    Set @num= ( ) -->asignación a @num de un valor, que va a ser el que devuelva la consulta que esta entre los paréntesis.

    Select isnull (Max(Numero),0)+1 --> Coge el maximo numero. Si max es nulo entonces pone un 0, y luego por precedencia de paréntesis, cuando haya terminado, max y isnull entonces le suma 1. Este valor con el cual tendremos el numero de cliente +1 se ve asignado a @num (POR EJEMPLO 9)

    Select @cadena --> Dos partes. La primera esta select retornará del procedure con lo que devuelva. La segunda es que de momento ya tenemos lo de la variable Temporal @cadena='NCL'

    +RIGHT(cast((   +@NUM) as varchar(5)),4) -->esto nos devuelve la parte derecha de una cadena que tiene algo más  9 que tiene @num, que es el maximo cliente +1 pero como una cadena.

    POWER(10,4) --> 10000 que sumados al número en cuestion serían 10009 pero como solo cogemos los 4 carácteres de la derecha tenemos 00009 + lo comentado, tenemos NCL0009.

    Con esto el procedure resuelve nuestra solicitud

    Refactorizado:

    ALTER PROCEDURE [dbo].[SP_CODIGO_CLIENTE]
    AS
        BEGIN
            SELECT 'NCL' + RIGHT(CAST((POWER(10, 4) + (ISNULL(MAX(numero), 0) + 1)) AS VARCHAR(5)), 4)
    
    		  FROM cliente
    
            RETURN;
        END;

    Adicional podría ser, que la cadena y la longitud fueran parámetros de manera que NCL y el número de digitos, se recibieran a la entrada del procedure y así el mismo, podría servir si el formato cambiase.

    Refactorizado con 1 parámetro:

    ALTER PROCEDURE [dbo].[SP_CODIGO_CLIENTE] (@cadena as varchar(4))
    AS
        BEGIN
            SELECT @cadena + RIGHT(CAST((POWER(10, 4) + (ISNULL(MAX(numero), 0) + 1)) AS VARCHAR(5)), 4)
    
    		  FROM cliente
    
            RETURN;
        END;

    Ahora la llamada espera recibir una variable tipo cadena de 4 caráteres máx. Por ejemplo NCL

    Codigo c#:

    var ConnectionString = xxx --> le asigno mi cadena de conexión a la base de datos con la que tengo que trabajar.

    using(SqlConnection conn = new SqlConnection(ConnectionString)){  } -->utilizamos un using para que la conexion creada contra la base de datos, dure, exactamente lo que dura el bloque, de este modo el propio código implementará el método dispose sobre la conexión y ocurra lo que ocurra la conexión se liberará. No ocupando el pool de conexiones que es limitado y consume muchos recursos.

    SqlCommand SqlCmd = new SqlCommand("sp_codigo_Cliente",conn); --> genero un objeto sqlcmd llamando a su constructor con el nombre del procedimiento y pasándole la conexión a la bbdd, por tanto ya tengo un objeto para ejecutar una sentencia sql.

    SqlCmd.CommandType = CommandType.StoredProcedure; --> a la sentencia le digo que es un Procedimiento almacenado.

    Luego utilizamos un bloque try catch para efectuar la conexión real a la base de datos. Aquí depende de como gestiones los errores. Cada maestrillo tiene su librillo en este punto, pero además de lo que hagas con el error, pensando en devolverlo al cliente o lo que sea, es muy razonable usar algún tipo de log en disco. Es bastante fácil de implementar la solución de log4net, pero esto es un plus.

     SqlCmd.Parameters.AddWithValue("@CADENA", "NCL"); --> El procedimiento almacenado esta esperando recibir un parámetro que se llama @cadena, por tanto le paso ese parámetro que se llama del mismo modo, y si tuviese más no tengo porque respetar el orden aunque es una buena forma de hacerlo, y el contenido que quiero que resuelva en este caso un literal NCL.

    conn.Open(); --> Abro la el tunel que me lleva directamente a mi base de datos.

    resultado = (string)SqlCmd.ExecuteScalar() ;-->Ejecuto la sentencia de tipo procedure, y le indico que me va a devolver una tabla de 1 fila por 1 columna. Este método es más eficiente, que executeReader. Además estoy seguro que el procedimiento almacenado me devuelve un valor porque he utilizado isnull. Este valor se lo asigno a la variable de tipo string resultado.

    Y fin.....

    Perdona por el rollo. Si tienes dudas, me matizas lo que necesitas.

    Un saludo

    viernes, 22 de febrero de 2019 5:49