Respondida Generar id

  • viernes, 27 de julio de 2012 1:21
     
      Tiene código

    Hola quiero generar id al momento de hacer un insert auna tabla que me genere el id siguiente tengo esto 

    CREATE FUNCTION GenerarId
    (   
        @Id    VARCHAR(50), 
        @Tabla VARCHAR(50) 
    )
        RETURNS INT
    AS
    BEGIN
     
        DECLARE @Max INT             -- Variable de Salida q me Captura el Id
        
        DECLARE @SQL NVARCHAR(MAX)   -- Variable para Ejecutar una Sentencia SQL    
        DECLARE @Param NVARCHAR(MAX) -- Variable para Mandar parametros a la Consulta
     
        SET @Param = N'@ParamId INT OUTPUT' -- Variable a Enviar
        SET @SQL = N'SELECT @ParamId = MAX(' + @Id + ') 
                     FROM ' + @Tabla + ';'
     
        EXECUTE SP_EXECUTESQL @SQL, @Param, @ParamId = @Max OUTPUT;
     
        IF @Max IS NULL
            SET @Max = 1;
        ELSE
            SET @Max = @Max + 1;
            
        RETURN @Max
    END

    como lo pruebo e intentado de esta manera EXEC GenerarId 'idarticulo', 'Articulos' par probar la funcion per se ejecuta correctamente pero no se la verdad como funciona este es mi insert:

    ALTER PROCEDURE [dbo].[xspAddArticulo]
    (
    @idArticulo varchar(6),
    @idCategoria int,
    @descripcion varchar(80),
    @precioPublico float,
    @costo float,
    @costoPromedio float,
    @cobraIva char(1)
    )
    AS
    BEGIN
    	
    	SET NOCOUNT ON;
    
       INSERT INTO Articulos(idarticulo, idcategoria, descripcion, preciopublico, costo, costopromedio, cobraiva)
         VALUES(@idCategoria, @idCategoria, @descripcion, @precioPublico, @costo, @costoPromedio, @cobraIva)
       
    END

    Me gustaría al momento de guardar me genere el id siguiente 


    Pedro Avila

Todas las respuestas

  • viernes, 27 de julio de 2012 4:10
     
     Respondida Tiene código

    Si usas SQL Server 2012 deberias usar los SEQUENCE, si estas en una versión anterior, cual es el problema con los campos IDENTITY?

    Si insistes en crear tu propia version de "secuencias" para invocar a esa funcion deberias hacer asi

    INSERT INTO Articulos(idarticulo, idcategoria, descripcion, preciopublico, costo, costopromedio, cobraiva)
         VALUES(dbo.GenerarId("idarticulo", "articulo") , @idCategoria, @descripcion, @precioPublico, @costo, @costoPromedio, @cobraIva)

    tienes que saber que a parte de tener los problemas tipicos del select max() para asignar valor a PK's, estás usando SQL Dinamico que empeora el rendimiento sin un motivo justificado..

    • Marcado como respuesta Pedro Avila sábado, 28 de julio de 2012 3:50
    •  
  • viernes, 27 de julio de 2012 11:29
     
     
    Hola Ronal, tu recomendación es que no genere el id con el sql pq? me quita rendimiento verdad? estoy usando sql 2005 express

    Pedro Avila

  • viernes, 27 de julio de 2012 12:39
    Moderador
     
     

    Hola.

    Lo más simple es que definas tu campo como identity. Y sólo si eso no lo puedes hacer o no cubre tu necesidad, plantéate alternativas.

    ¿Puedes emplear un identity?


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

  • viernes, 27 de julio de 2012 13:08
     
     
    Hola en mi cmapo idArticulo es de tipo varcahar(6) y los id son en este formato(000001,000002, etc) eso lo genero por código vb.net  pero pense hacerlo por sql pero Ronald me aconseja que no pq? le quito rendimiento al sql

    Pedro Avila

  • sábado, 28 de julio de 2012 3:51
     
     

    Hola Ronald,

    Aque te refieres con SQL dinamico


    Pedro Avila

  • sábado, 28 de julio de 2012 17:53
     
     Respondida

    Utilizar select max() para asignar una pk puede retornarte errores de pk duplicada en altas concurrencias, aunque en tu caso estas minimizando la ventana de error por obtenerlo en el momento del insert.

    En cuanto al sql dinamico, el mismo ralentiza la ejecución de querys y solo debes utilizarlo cuando es realmente necesario y no tienes otra solucion.. este ralentizamiento se debe a que se tiene que volver a comprobar la sintaxis, compilar la query, cada vez que lo ejecutas, y depende de la versión del motor que uses puede no utilizar estadisticas de ejecucion. El concepto se explica aqui http://www.devjoker.com/contenidos/catss/308/SQL-din%C3%A1mico-en-Transact-SQL.aspx

    No entiendo porque quieres reinventar la rueda si tienes la posibilidad de usar el IDENTITY y apararemente cubre tus necesidades..

    A modo de anecdota laboral te cuento un caso que sucedió en una empresa telefonica, uno de los procedimientos que se debían correr usaba SQL dinamico y dependiendo del caso se podia generar 37 posibles querys distintas, ese proceso tardaba casi 2 horas en terminar de ejecutarse, cuando creamos las 37 posibles querys en procedimientos almacenados distintos con sql estatico y segun el caso decidiamos ejecutar uno u otro, el tiempo de ejecución se redujo a poco más de 15 minutos.. aunque para el caso que expones no tendras un retardo de 2 horas, es recomendable no poner en práctica estas técnicas cuando no son realmente necesarias..

  • sábado, 28 de julio de 2012 18:33
     
     
    Ok, Ronald quedo todo claro gracias por la ayuda y la información.

    Pedro Avila