sql-server - salida - procedimiento almacenado sql server select
¿Cómo creo condicionalmente un procedimiento almacenado en SQL Server? (10)
Controlar su base de datos es el camino a seguir, pero ... ¿Por qué crear procedimientos almacenados de manera condicional? Para Vistas, procedimientos almacenados, funciones, simplemente colóquelos condicionalmente y recíclelos cada vez. Si crea condicionalmente, entonces no limpiará las bases de datos que tienen un problema o un truco que pusieron hace 2 años otro desarrollador (usted o yo nunca haríamos esto) que estaba seguro de que recordaría eliminar la única vez actualización de emergencia.
Como parte de mi estrategia de integración, tengo algunos scripts SQL que se ejecutan para actualizar la base de datos. Lo primero que hacen todos estos scripts es verificar si necesitan ejecutarse, por ejemplo:
if @version <> @expects
begin
declare @error varchar(100);
set @error = ''Invalid version. Your version is '' + convert(varchar, @version) + ''. This script expects version '' + convert(varchar, @expects) + ''.'';
raiserror(@error, 10, 1);
end
else
begin
...sql statements here...
end
¡Funciona genial! Excepto si necesito agregar un procedimiento almacenado. El comando "create proc" debe ser el único comando en un lote de comandos sql. Poner un "proceso de creación" en mi instrucción IF causa este error:
''CREATE/ALTER PROCEDURE'' must be the first statement in a query batch.
¡Ay! ¿Cómo coloco el comando CREATE PROC en mi script, y solo lo ejecuto si es necesario?
Debo admitir que, normalmente, estaría de acuerdo con @Peter: dejo caer condicionalmente y luego recreé incondicionalmente todo el tiempo. Me han atrapado demasiadas veces en el pasado cuando intentaba adivinar las diferencias de esquema entre bases de datos, con o sin cualquier forma de control de versión.
Habiendo dicho eso, tu propia sugerencia @Josh es genial. Ciertamente interesante. :-)
Este es un hilo antiguo, pero Jobo es incorrecto: Create Procedure debe ser la primera declaración en un lote. Por lo tanto, no puede usar Exists
para probar la existencia y luego usar Create
o Alter
. Lástima.
Esto es lo que se me ocurrió:
Envuélvalo en un EXEC (), así:
if @version <> @expects
begin
...snip...
end
else
begin
exec(''CREATE PROC MyProc AS SELECT ''''Victory!'''''');
end
¡Funciona de maravilla!
Mi solución es comprobar si existe el proceso, si es así, soltarlo y luego crear el proceso (la misma respuesta que @robsoft pero con un ejemplo ...)
IF EXISTS(SELECT * FROM sysobjects WHERE Name = ''PROC_NAME'' AND xtype=''P'')
BEGIN
DROP PROCEDURE PROC_NAME
END
GO
CREATE PROCEDURE PROC_NAME
@value int
AS
BEGIN
UPDATE SomeTable
SET SomeColumn = 1
WHERE Value = @value
END
GO
Pero tenga cuidado con las comillas simples dentro de su Procedimiento almacenado: deben "escaparse" agregando un segundo. La primera respuesta ha hecho esto, pero solo en caso de que te lo hayas perdido. Una trampa para jugadores jóvenes.
Problema al eliminar y crear es que pierde cualquier concesión de seguridad que se haya aplicado anteriormente al objeto que se descarta.
SET NOEXEC ON es una buena forma de desactivar alguna parte del código
IF NOT EXISTS (SELECT * FROM sys.assemblies WHERE name = ''SQL_CLR_Functions'')
SET NOEXEC ON
GO
CREATE FUNCTION dbo.CLR_CharList_Split(@list nvarchar(MAX), @delim nchar(1) = N'','')
RETURNS TABLE (str nvarchar(4000)) AS EXTERNAL NAME SQL_CLR_Functions.[Granite.SQL.CLR.Functions].CLR_CharList_Split
GO
SET NOEXEC OFF
Se encuentra aquí: https://codereview.stackexchange.com/questions/10490/conditional-create-must-be-the-only-statement-in-the-batch
PD Otra forma es SET PARSEONLY {ON | APAGADO }.
utilice el comando ''Existe'' en T-SQL para ver si existe el proceso almacenado. Si lo hace, usa ''Alter'', sino usa ''Crear''
IF NOT EXISTS(SELECT * FROM sys.procedures WHERE name = ''pr_MyStoredProc'')
BEGIN
CREATE PROCEDURE pr_MyStoredProc AS .....
SET NOCOUNT ON
END
ALTER PROC pr_MyStoredProc
AS
SELECT * FROM tb_MyTable