我有一个存储过程,它会删除大量的记录,数十万条。虽然不会从应用程序中运行,但我仍然担心我的客户之一会意外运行它(由于他们的“好奇心”,我之前就遇到过问题):D
是的,有备份等等,但我在想……不要吓唬他们……有没有一种方法在执行之前询问用户“你确定?”? :) 谢谢
我有一个存储过程,它会删除大量的记录,数十万条。虽然不会从应用程序中运行,但我仍然担心我的客户之一会意外运行它(由于他们的“好奇心”,我之前就遇到过问题):D
是的,有备份等等,但我在想……不要吓唬他们……有没有一种方法在执行之前询问用户“你确定?”? :) 谢谢
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
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
...
请注意,特殊代码必须是'SpecialCode'或者当达到RETURN 999时。
@reallyReallyReallyDelete
参数,作为安全措施:如果将其设置为 YesYesYes
,则会实际提交事务。这里有另一种方法,我认为适用于用户直接调用过程而不是从应用程序中调用的特定情况。
我必须说,与大多数其他建议相比,它对用户提出的问题较少,但对开发人员提出的问题更多(也许是不成比例的)。您可以决定它是否适合您。
无论如何,下面开始。
首先,您需要创建一个特殊的表CriticalCalls
,以注册对关键过程的调用。该表的结构如下:
SPID int,
ProcName sysname,
CallTime datetime
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 */
CheckCriticalCalls
)来处理所有与CriticalCalls
相关的操作,包括所有必要的修改。 CheckCriticalCalls
将接收要检查的过程名称,并返回一种标志,显示指定的过程是否应执行其真正的操作。EXECUTE @result = CheckCriticalCalls 'ThisProcedureName';
IF @result = -1 BEGIN
PRINT 'Call me again';
RETURN;
END;
... /* go on with the task */
EXECUTE...
行,从而自动调用关键过程两次。 当然,上限是必要的,以确保用户确认他们最近的意图执行关键操作;如果CriticalCalls
中的现有记录实际上是留给具有相同SPID的过去会话,则防止执行。@UserKnowsWhatTheyAreDoing
的位输入,在执行之前检查其是否为真。如果为假,请打印友好的消息并从过程中优雅地返回。'是的,我知道我在做什么'
。或者它可能会在一个特殊表格中查找一行具有类似确认和最近时间戳的内容。