none
Como declarar un procedimiento almacenado que valida object_id() RRS feed

  • Pregunta

  • Saludos compañeros, estoy creando un storeprocedure que debe validar si el objeto tabla existe, lel script que tengo es el siguiente:

    use negocios
    go
    create procedure DesactivaMayoristas_update
    as
    begin
    /* paso 1 (RESPALDO)*/
    if OBJECT_ID(N'productosmayoristas','U') IS NOT NULL
    DROP TABLE productosmayoristas
    GO
    select codigo,producto,precio,precio2 ,precio3,unidad_p2,unidad_p3 into productosmayoristas from productos where precio2>0 or precio3>0 
    go
    /* paso 2 (DESACTIVA MAYORISTAS)*/
    --waitfor delay '00:00:05'
    update productos set precio2=0,precio3 =0,unidad_p2=0,unidad_p3=0 where codigo in (select codigo from productosmayoristas)
    set XACT_ABORT on --Control simple para transaccion
    
    end
    go
    grant exec on DesactivaMayoristas_update to public
    go
    

    pero resulta que cuando lo crea , solamente me pone la primer parte del código, y no realiza las instrucciones del insert y update.

    Como sería la separación de instrucciones ?


    La programacion en Microsoft cada ves se torna inalcanzable

    domingo, 14 de julio de 2019 4:08

Todas las respuestas

  • Es por el "GO". Ese "GO" significa "aquí se acaba el procedimiento almacenado", y por eso no te toma el resto. No puedes poner un GO dentro de un procedimiento. Eso a su vez implica que no se puede escribir un procedimiento almacenado que contenga alguna de las sentencias que obligatoriamente tienen que ir aisladas dentro de un lote, y no permiten que haya detrás otras sentencias dentro del mismo lote. Pero creo que el "drop table" no es una de estas sentencias, así que debería funcionar si sencillamente eliminas el GO.
    domingo, 14 de julio de 2019 7:21
  • Hola Alfonso_tecnicopa:

    Go es una instrucción que no es TSQL, y solo reconocen las utilidades sqlcmd, y osql y el Editor del Management Studio, Azure Data Studio (antes Operations Studio).

    Instrucciones de utilidades SQL Server GO

    https://docs.microsoft.com/es-es/sql/t-sql/language-elements/sql-server-utilities-statements-go?view=sql-server-2017

    Pero además tú procedure parece a priori tener más problemas.

    Si el procedure inicia con un BEGIN, tiene que terminar con un END. Al haber esos GO no hay end.

    Si pegas el mismo en tú editor, te marcará el Intellisense en rojo el primer GO.

    CREATE PROCEDURE DesactivaMayoristas_update 
    AS
    BEGIN
        SET XACT_ABORT ON -- Control de la transaccion si algo falla, se aborta todo
    
        IF (OBJECT_ID(N'productosmayoristas','U') IS NOT NULL)
            DROP TABLE productosMayoristas;
        
        Select codigo,producto,precio,precio2 ,precio3,unidad_p2,unidad_p3
             into productosmayoristas 
             from productos where precio2>0 or precio3>0;
        
        update productos set precio2= 0, precio3=0, unidad_p2=0, unidad_p2 =0
            where codigo in 
            (
                Select codigo from productosmayoristas
            );
        
    END;

    No parece tener mucho sentido que un procedure se de permisos a el mismo, esto se establecerá en otra ejecución.

    Un poco más elegante, es en vez de utilizar el operador in utilizar una inner join entre productos y productosmayoristas, para saber cuales vas a updatear.

    CREATE PROCEDURE DesactivaMayoristas_update 
    AS
    BEGIN
        SET XACT_ABORT ON -- Control de la transaccion si algo falla, se aborta todo
    
        IF (OBJECT_ID(N'productosmayoristas','U') IS NOT NULL)
            DROP TABLE productosMayoristas;
        
        Select codigo,producto,precio,precio2 ,precio3,unidad_p2,unidad_p3
             into productosmayoristas 
             from productos where precio2>0 or precio3>0;
        
        update productos set precio2= 0, precio3=0, unidad_p2=0, unidad_p2 =0
        from productos inner join productosmayoristas m on productos.codigo = m.codigo;
        
    END;
    

    • Propuesto como respuesta eRiver1 lunes, 15 de julio de 2019 4:47
    domingo, 14 de julio de 2019 18:48
  • Hola Alfonso_tecnicopa:

    Go es una instrucción que no es TSQL, y solo reconocen las utilidades sqlcmd, y osql y el Editor del Management Studio, Azure Data Studio (antes Operations Studio).

    Instrucciones de utilidades SQL Server GO

    https://docs.microsoft.com/es-es/sql/t-sql/language-elements/sql-server-utilities-statements-go?view=sql-server-2017

    CREATE PROCEDURE DesactivaMayoristas_update 
    AS
    BEGIN
        SET XACT_ABORT ON -- Control de la transaccion si algo falla, se aborta todo
    
        IF (OBJECT_ID(N'productosmayoristas','U') IS NOT NULL)
            DROP TABLE productosMayoristas;
        
        Select codigo,producto,precio,precio2 ,precio3,unidad_p2,unidad_p3
             into productosmayoristas 
             from productos where precio2>0 or precio3>0;
        
        update productos set precio2= 0, precio3=0, unidad_p2=0, unidad_p2 =0
            where codigo in 
            (
                Select codigo from productosmayoristas
            );
        
    END;

    No parece tener mucho sentido que un procedure se de permisos a el mismo, esto se establecerá en otra ejecución.


    Ok corregí lo del begin, pero lo de los permisos lo pongo porque me ha pasado que cuando intento conectarme remotamente, les pasa que bota el mensaje de 'no tiene permisos para ejecutar el procedimiento almacenado' y se supone que cuando lo creo el procedimiento estoy logueado como sa y cuando la aplicación lo ejecuta utiliza otro usuario.

    La programacion en Microsoft cada ves se torna inalcanzable

    miércoles, 17 de julio de 2019 2:28
  • Hola alfonso_tecnicopa,

    Me parece que tu realmente estás teniendo un problema con intentar mantenerte en la vanguardia o la modernidad en lo que se refiere a desarrollar los lenguajes que tu manejas con la manera en que se enlazan plataformas modernas, como bien sabras SQL Server puede permitir varias conexiones simultaneas y todas estas con diferentes permisos de acceso a la información; y te lo voy a comentar así a diferencia de otros sitios o otras compañías el acceso a la información es privilegiada y está regulada, es decir en un MySQL quizá solo seas tu quien entra a DB pero en SQL Server quizá entres tú o tu compañero a hacer "querys" o quizá tengas montado un sistema en el cual necesitas que 2000 usuarios entren a realizar consultas cada segundo, me refiero a quizá está realizando ventas, o compras, transacciones o variadas cantidad de operaciones. FRONT MIDDLE BACK digamos en un ERP o un CRM.

    De hecho existe una versión más ligera para SQL Server - https://www.microsoft.com/en-us/sql-server/sql-server-editions-express 

    Realmente le recomiendo considerar y analizar si usted necesita un producto del tipo "SERVER" para sus desarrollos y si está familiarizado con el por qué es que existen varios usuarios y varios niveles de acceso a las 1 o miles de DB que puede tener con el producto SQL Server.

    Gracias por usar los foros de MSDN.
    Erick Rivera
     ____
    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.
    Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft. 
    Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft.
    lunes, 22 de julio de 2019 6:04