我具有被做了很多的删除的存储过程。成千上万的记录。它不会是可运行从应用程序,不过,我担心,我的一个客户不小心运行它(我不得不因自己的“好奇心”前面的问题):d

是。有备份和类似的东西,但我想....不是吓唬他们...有没有办法来询问用户“你确定吗?”之前执行呢? :) 感谢

有帮助吗?

解决方案

我想你可以有一个名为“确认”参数,需要一个特定的字符串(E,G,“我知道我在做什么”)的传递,如果没有设置,或设置不正确,只是从过程返回,而不执行主代码。不正是你想要的东西,但它是一个选项。

例如 - (未经测试,可能可怕语法)

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

其他提示

在短,无

在理论上来说,任何人的权限,以查找并能够运行一个存储过程,应该被允许。这将是更好的限制权限,使那些与过量的好奇心不必运行此权限。

另外,安全性较低,选择是需要一个预定义的秘密,需要作为一个参数传递 - 当然,他们可能只是脚本关闭存储过程来寻找秘密,但...

当然,另一点是:如果不是调用,包括为什么呢?毕竟,当你来到做管理型的任务,你可以有脚本了作为一个文件,你可以保持安全你自己的机器上的陈述。

使用一个多层入手:

1)控制执行的安全性,如下:

GRANT EXECUTE ON [dbo].[yourProcedure] TO [userxyz]

2)使用真描述/吓人程序的名称,如

CREATE PROCEDURE Will_Delete_All_Your_Data ...

3)把一个大的醒目评论在存储过程

的开始
--NOTE, will delete all of your data--
--NOTE, will delete all of your data--
--NOTE, will delete all of your data--
--NOTE, will delete all of your data--
--NOTE, will delete all of your data--

4)使用户通以模糊特殊接入码:

CREATE PROCEDURE Will_Delete_All_Your_Data
(
    @SpecialCode varchar(30)
)

IF @SpecialCode!=CHAR(83)+CHAR(112)+CHAR(101)+CHAR(99)+CHAR(105)+CHAR(97)+CHAR(108)+CHAR(67)+CHAR(111)+CHAR(100)+CHAR(101)
BEGIN
    RETURN 999
END
...

FYI,特殊码必须是 'SpecialCode' 或RETURN 999是命中。

您可以将@reallyReallyReallyDelete参数添加到存储过程,这将作为一项安全措施:如果它被设置为YesYesYes实际上将提交事务

您可以使用一个位输入称为@UserKnowsWhatTheyAreDoing和检查,看看它是否在执行之前如此。如果是假的,打印一个友好的消息,并从程序优雅地恢复

该过程可能需要具有特定的值的参数,如'Yes I know what I'm doing'。或者,它可能会寻找一个排的具有类似的确认和最近的时间戳一个特殊的表。

这里的又一种方法中,我认为是适合当一个过程是由用户直接而不是从应用程序调用的特定情况下。

我必须说,它提出了用户少一些麻烦,而更多的(也许,不成比例),用于比较的开发商与大多数其他建议。您确定它是否适合你。

总之,在这里不用。

首先,创建一个特殊的表,CriticalCalls,注册到关键过程的调用。的表将具有这样的结构:

SPID int,
ProcName sysname,
CallTime datetime

基本上,这个想法是,一个关键的SP应该被称为两次:第一次它注册其呼叫,并通知用户的时间作为其意图确认在一定时间间隔内重复该呼叫,并与所述第二呼叫,如果据此作出,它实际上与完成任务进行。

所以每次关键过程的起始部分将具有这样的逻辑:

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 */

事实上,我认为,这将是最好用于所有的操作专用的SP(下面称为CheckCriticalCalls)与CriticalCalls,包括所有必要的修改。 CheckCriticalCalls将接收名的程序进行检查,并返回一种标志的显示指定的程序是否应执行它的实际工作情况。

因此,它可能看起来有点像这样的:

EXECUTE @result = CheckCriticalCalls 'ThisProcedureName';
IF @result = -1 BEGIN
  PRINT 'Call me again';
  RETURN;
END;

...  /* go on with the task */

后面设定该间隔的下限的想法是仅仅是为了防止用户调用一个关键步骤两次自动,即通过在一个批处理执行两个相同EXECUTE...线。的上限,当然是必要的:1)确保用户确认他们的非常近的意图来执行关键的操作; 2)防止执行如果CriticalCalls现有记录是从过去的会话使用相同的SPID实际上离开那里。

因此,基本上,1-2秒至半分钟的间隔似乎很自然的我。你可以选择不同的数字来代替。

你需要真正从数据库中删除?如果我能负担得起额外的空间,我会在我的表一个“删除”标记和最后更新的列。这样,如果一个记录至少误删除我通常可以跟踪下来,并很容易恢复。只是一个想法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top