teclas - tips sql server management studio
Comando T-SQL STOP o ABORT en SQL Server (9)
¿Por qué no simplemente agrega lo siguiente al comienzo de la secuencia de comandos?
PRINT ''INACTIVE SCRIPT''
RETURN
¿Hay algún comando en Microsoft SQL Server T-SQL que indique a la secuencia de comandos que detenga el procesamiento? Tengo un script que quiero guardar para fines de archivo, pero no quiero que nadie lo ejecute.
A pesar de su descripción muy explícita y contundente, RETORNO no funcionó para mí dentro de un procedimiento almacenado (para omitir la ejecución posterior). Tuve que modificar la lógica de la condición. Ocurre en SQL 2008, 2008 R2:
create proc dbo.prSess_Ins
(
@sSessID varchar( 32 )
, @idSess int out
)
as
begin
set nocount on
select @id= idSess
from tbSess
where sSessID = @sSessID
if @idSess > 0 return -- exit sproc here
begin tran
insert tbSess ( sSessID ) values ( @sSessID )
select @idSess= scope_identity( )
commit
end
tuvo que ser cambiado a:
if @idSess is null
begin
begin tran
insert tbSess ( sSessID ) values ( @sSessID )
select @idSess= scope_identity( )
commit
end
Descubierto como resultado de encontrar filas duplicadas. Las IMPRESIONES de depuración confirmaron que @idSess tenía un valor mayor que cero en la verificación IF. ¡RETORNO no interrumpió la ejecución!
Aquí hay una manera algo complicada de hacerlo que funciona con GO-batches, al usar una variable "global".
if object_id(''tempdb..#vars'') is not null
begin
drop table #vars
end
create table #vars (continueScript bit)
set nocount on
insert #vars values (1)
set nocount off
-- Start of first batch
if ((select continueScript from #vars)=1) begin
print ''1''
-- Conditionally terminate entire script
if (1=1) begin
set nocount on
update #vars set continueScript=0
set nocount off
return
end
end
go
-- Start of second batch
if ((select continueScript from #vars)=1) begin
print ''2''
end
go
Y aquí está la misma idea utilizada con una transacción y un bloque try / catch para cada GO-batch. Puede intentar cambiar las diversas condiciones y / o dejar que genere un error (dividir por 0, ver comentarios) para probar cómo se comporta:
if object_id(''tempdb..#vars'') is not null
begin
drop table #vars
end
create table #vars (continueScript bit)
set nocount on
insert #vars values (1)
set nocount off
begin transaction;
-- Batch 1 starts here
if ((select continueScript from #vars)=1) begin
begin try
print ''batch 1 starts''
if (1=0) begin
print ''Script is terminating because of special condition 1.''
set nocount on
update #vars set continueScript=0
set nocount off
return
end
print ''batch 1 in the middle of its progress''
if (1=0) begin
print ''Script is terminating because of special condition 2.''
set nocount on
update #vars set continueScript=0
set nocount off
return
end
set nocount on
-- use 1/0 to generate an exception here
select 1/1 as test
set nocount off
end try
begin catch
set nocount on
select
error_number() as errornumber
,error_severity() as errorseverity
,error_state() as errorstate
,error_procedure() as errorprocedure
,error_line() as errorline
,error_message() as errormessage;
print ''Script is terminating because of error.''
update #vars set continueScript=0
set nocount off
return
end catch;
end
go
-- Batch 2 starts here
if ((select continueScript from #vars)=1) begin
begin try
print ''batch 2 starts''
if (1=0) begin
print ''Script is terminating because of special condition 1.''
set nocount on
update #vars set continueScript=0
set nocount off
return
end
print ''batch 2 in the middle of its progress''
if (1=0) begin
print ''Script is terminating because of special condition 2.''
set nocount on
update #vars set continueScript=0
set nocount off
return
end
set nocount on
-- use 1/0 to generate an exception here
select 1/1 as test
set nocount off
end try
begin catch
set nocount on
select
error_number() as errornumber
,error_severity() as errorseverity
,error_state() as errorstate
,error_procedure() as errorprocedure
,error_line() as errorline
,error_message() as errormessage;
print ''Script is terminating because of error.''
update #vars set continueScript=0
set nocount off
return
end catch;
end
go
if @@trancount > 0 begin
if ((select continueScript from #vars)=1) begin
commit transaction
print ''transaction committed''
end else begin
rollback transaction;
print ''transaction rolled back''
end
end
Intente ejecutar esto como un script de TSQL
SELECT 1
RETURN
SELECT 2
SELECT 3
El regreso termina la ejecución.
Sale incondicionalmente de una consulta o procedimiento. RETORNO es inmediato y completo y puede utilizarse en cualquier punto para salir de un procedimiento, lote o bloque de instrucción. Las declaraciones que siguen a RETORNO no se ejecutan.
No, no hay uno, tienes un par de opciones:
Envuelva todo el script en un gran bloque if / end que simplemente garantice que no sea verdadero (es decir, "si 1 = 2 begin" - esto solo funcionará si el script no incluye ninguna instrucción GO (ya que eso indica un nuevo lote)
Use la declaración de devolución en la parte superior (nuevamente, limitada por los separadores de lotes)
Utilice un enfoque basado en la conexión, que garantizará la no ejecución de todo el script (toda la conexión será más precisa); use algo como ''SET PARSEONLY ON'' o ''SET NOEXEC ON'' en la parte superior del script. Esto asegurará que todas las declaraciones en la conexión (o hasta que dicha declaración establecida se desactive) no se ejecutarán y en su lugar solo se analizarán / compilarán.
Use un bloque de comentarios para comentar todo el script (es decir, / * y * /)
EDITAR: Demostración de que la declaración ''return'' es específica del lote: tenga en cuenta que continuará viendo los conjuntos de resultados después de los retornos:
select 1
return
go
select 2
return
select 3
go
select 4
return
select 5
select 6
go
Para RAISERROR (''Oi! Stop!'', 20, 1) WITH LOG
problema RETURN / GO, puede colocar RAISERROR (''Oi! Stop!'', 20, 1) WITH LOG
en la parte superior.
Esto cerrará la conexión del cliente según RAISERROR en MSDN .
La gran desventaja es que tienes que ser administrador de sistemas para usar severidad 20.
Editar:
Una simple demostración para contrarrestar el comentario de Jersey Dude ...
RAISERROR (''Oi! Stop!'', 20, 1) WITH LOG
SELECT ''Will not run''
GO
SELECT ''Will not run''
GO
SELECT ''Will not run''
GO
RAISERROR con gravedad 20 se informará como error en el Visor de eventos.
Puede usar SET PARSEONLY ON; (o NOEXEC). Al final del script, usa GO SET PARSEONLY OFF;
SET PARSEONLY ON;
-- statement between here will not run
SELECT ''THIS WILL NOT EXEC'';
GO
-- statement below here will run
SET PARSEONLY OFF;
Sé que la pregunta es antigua y fue respondida correctamente de diferentes maneras, pero no hay ninguna respuesta como la mía que he usado en situaciones similares. Primer enfoque (muy básico):
IF (1=0)
BEGIN
PRINT ''it will not go there''
-- your script here
END
PRINT ''but it will here''
Segundo enfoque:
PRINT ''stop here''
RETURN
-- your script here
PRINT ''it will not go there''
Puede probarlo fácilmente usted mismo para asegurarse de que se comporte como se esperaba.
Una solución alternativa podría ser alterar el flujo de ejecución de su script mediante el uso de la declaración GOTO
...
DECLARE @RunScript bit;
SET @RunScript = 0;
IF @RunScript != 1
BEGIN
RAISERROR (''Raise Error does not stop processing, so we will call GOTO to skip over the script'', 1, 1);
GOTO Skipper -- This will skip over the script and go to Skipper
END
PRINT ''This is where your working script can go'';
PRINT ''This is where your working script can go'';
PRINT ''This is where your working script can go'';
PRINT ''This is where your working script can go'';
Skipper: -- Don''t do nuttin!
¡Advertencia! La muestra anterior se derivó de un ejemplo que obtuve de Merrill Aldrich. Antes de implementar la declaración GOTO
ciegas, le recomiendo que lea su tutorial sobre Control de flujo en scripts T-SQL .