Existe uma "você tem certeza" para a execução do procedimento armazenado? :)
-
23-09-2019 - |
Pergunta
Eu tenho um procedimento armazenado que está fazendo muita exclusão. Centenas de milhares de registros. Não será executável a partir do aplicativo, mas ainda estou preocupado, que um dos meus clientes acidentalmente o administra (tive problemas mais cedo devido à "curiosidade"): D
Sim. Existem backups e coisas assim, mas eu estava pensando ... para não assustá -los ... existe uma maneira de perguntar ao usuário "Você tem certeza?" antes de executá -lo? :) obrigado
Solução
Eu acho que você poderia ter um parâmetro chamado "confirmação" que requer uma string específica (e, g, "eu sei o que estou fazendo") para ser passado, se não estiver definido ou está definido incorretamente, basta retornar do procedimento sem executar o código principal. Não é exatamente o que você queria, mas é uma opção.
por exemplo - (sintaxe não testada e provavelmente terrível)
CREATE PROCEDURE dbo.mySproc (
@Confirmation Varchar(100)
) AS
BEGIN
if(@Confirmation <> 'I know what I am doing')
BEGIN
return;
END
DELETE from table_name where condition
END
Outras dicas
Em suma, não.
A teoria diz que qualquer pessoa com permissões para encontrar e poder executar um procedimento armazenado deve ser permitido. Seria melhor restringir as permissões para que aqueles com excesso de curiosidade não tenham permissões para executar isso.
A outra opção, menos segura, seria exigir um segredo predefinido que precisa ser aprovado como um parâmetro - é claro que eles poderiam apenas escrever o procedimento armazenado para encontrar o segredo ...
Obviamente, o outro ponto seria: se não for chamável, por que incluí -lo? Afinal, quando você estiver fazendo tarefas do tipo de administrador, você pode ter as declarações roteirizadas como um arquivo que você pode manter em sua própria máquina
A maneira mais simples de fazer isso é criar um novo aplicativo da Web de modo clássico em 2013 (consulte http://technet.microsoft.com/en-us/library/gg276326.aspx ).Em seguida, use o artigo que você mencionou em sua pergunta para converter o aplicativo da Web para o modo de reivindicações depois de conectar seu banco de dados de conteúdo.
Você pode adicionar um @reallyReallyReallyDelete
parâmetro para o sproc, que servirá como uma medida de segurança: se estiver definido como YesYesYes
realmente comprometerá a transação.
Você pode usar uma entrada de um pouco chamada @UserKnowsWhatTheyAreDoing
e verifique se é verdade antes de executar. Se for falso, imprima uma mensagem amigável e retorne graciosamente do procedimento
Existem apenas algumas instâncias em que você obtém qualquer benefício real da compatibilidadeLevel tendo ambos 14 e 15. Se você tiver uma solução em que você está adicionando arquivos fantasmagóricos a um site, receberá avisos de analisadores de saúde que os arquivos nãot existe no 15 colmor se você estiver implantando apenas no modo 14.Outra instância está tendo definições do site para 2010 e 2013 na mesma solução de 2010.
Nós, no Newsgator, temos um grande número de soluções de 2010 que instalamos para 2013. O único caso que usamos a compatibilidadeLevel é quando temos arquivos Ghosted.
Aqui está outra abordagem, que eu acho que é adequada para o caso específico quando um procedimento deve ser chamado diretamente por um usuário e não por um aplicativo.
Devo dizer que propõe menos problemas para o usuário, embora mais (talvez, desproporcionalmente) para o desenvolvedor em comparação com a maioria das outras sugestões. Você decide se isso combina com você.
Enfim, aqui vai.
Primeiro, você cria uma tabela especial, CriticalCalls
, para registrar chamadas para procedimentos críticos. A tabela teria uma estrutura como esta:
SPID int,
ProcName sysname,
CallTime datetime
Basicamente, a idéia é que um SP crítico seja chamado duas vezes: primeiro registra sua chamada e informa o usuário a repetir a chamada dentro de um determinado intervalo de tempo como uma confirmação de sua intenção e com a segunda chamada, se feita de acordo, Na verdade, ele prossegue com a conclusão de sua tarefa.
Portanto, a parte inicial de todos os procedimentos críticos teria essa 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 */
Na verdade, eu acho, seria melhor usar um SP dedicado (chamado CheckCriticalCalls
abaixo) para todas as manipulações com CriticalCalls
, incluindo todas as modificações necessárias. CheckCriticalCalls
receberia o nome do procedimento a ser verificado e retornaria uma espécie de sinalizador mostrando se o procedimento especificado deve executar sua operação real.
Então pode parecer assim:
EXECUTE @result = CheckCriticalCalls 'ThisProcedureName';
IF @result = -1 BEGIN
PRINT 'Call me again';
RETURN;
END;
... /* go on with the task */
A idéia por trás do estabelecimento do limite inferior do intervalo é apenas para impedir que o usuário chamasse um procedimento crítico duas vezes automaticamente, ou seja, executando dois idênticos EXECUTE...
linhas em um lote. O limite superior, é claro, é necessário para 1) garantir que o usuário confirme sua intenção muito recente de executar a operação crítica; 2) impedir a execução se o registro existente em CriticalCalls
é realmente deixado lá de uma sessão passada com o mesmo SPID.
Então, basicamente, um intervalo de 1-2 segundos a meio minuto parece bastante natural para mim. Você pode escolher figuras diferentes.
Você precisa realmente excluí -los do banco de dados? Se eu puder pagar o espaço extra, colocarei uma bandeira 'excluída' nas minhas mesas e uma última coluna atualizada. Dessa forma, se um registro for excluído acidentalmente, pelo menos eu posso rastreá -lo e restaurá -lo com bastante facilidade. Apenas um pensamento.