Aquí hay otro enfoque, que creo que es adecuado para el caso particular cuando un procedimiento debe ser llamado por un usuario directamente en lugar de desde una aplicación.
Debo decir que propone menos problemas para el usuario y más (quizás, desproporcionadamente) para el desarrollador en comparación con la mayoría de las otras sugerencias. Tú decides si te conviene.
De todos modos, aquí va.
Primero, cree una tabla especial, CriticalCalls
, para registrar llamadas a procedimientos críticos. La tabla tendría una estructura como esta:
SPID int,
ProcName sysname,
CallTime datetime
Básicamente, la idea es que un SP crítica debe ser llamado dos veces: primero se registra su llamada e informa al usuario que repita la llamada dentro de un cierto intervalo de tiempo que una confirmación de su intención, y con la segunda llamada, si se realiza en consecuencia, en realidad procede a completar su tarea.
Así que la parte inicial de cada procedimiento crítico tendría esta lógica:
IF NOT EXISTS (
SELECT *
FROM CriticalCalls
WHERE SPID = @@SPID AND ProcName = @ThisProcName
AND GETDATE() - CallTime BETWEEN @LowerCallTimeLimit AND @UpperCallTimeLimit
/* the actual test for the time interval might be somewhat different */
) BEGIN
... /* upsert CriticalCalls with the current time stamp */
PRINT 'To proceed, please call this procedure again within...';
RETURN;
END;
DELETE FROM CriticalCalls WHERE SPID = @@SPID AND ProcName = @ThisProcName;
... /* proceed with your critical task */
En realidad, creo, sería mejor utilizar un SP específico (llamado CheckCriticalCalls
abajo) para todas las manipulaciones con CriticalCalls
, incluyendo todas las modificaciones necesarias. CheckCriticalCalls
recibiría el nombre del procedimiento que se comprobará y devolverá un tipo de indicador que muestra si el procedimiento especificado debe realizar su operación real.
lo tanto, podría parecer algo así como esto:
EXECUTE @result = CheckCriticalCalls 'ThisProcedureName';
IF @result = -1 BEGIN
PRINT 'Call me again';
RETURN;
END;
... /* go on with the task */
La idea de establecer el límite inferior del intervalo es simplemente para evitar que el usuario llama a un procedimiento crítico dos veces de forma automática, es decir, mediante la ejecución de dos idénticos EXECUTE...
líneas en un lote El límite superior, por supuesto, es necesario para 1) garantizar que el usuario confirme su intención muy reciente de realizar la operación crítica; 2) evitar la ejecución si el registro existente en CriticalCalls
se deja allí desde una sesión pasada con el mismo SPID.
Así que, básicamente, un intervalo de 1-2 segundos a medio minuto me parecería bastante natural. Puede elegir diferentes figuras en su lugar.
¿Por qué no configura permisos para sus procs almacenados? De esta forma, solo los usuarios autorizados pueden ejecutarlo. –
@ The Elite Gentleman: No estoy diciendo que los usuarios autorizados a veces deseen sentirse como seres humanos en lugar de máquinas. Este caso particular muestra más bien que a algunos desarrolladores no les importa percibir a los usuarios como meros mortales. :) –