문제

I have a stored procedure which is doing a lot of delete. Hundreds of thousands of records. It is not going to be runnable from the application, but still, i am concerned, that one of my clients accidentally runs it (i had problems earlier due to their "curiosity") :D

Yes. there are backups and stuff like that, but I was thinking .... not to scare them ... is there a way to ask the user "are you sure?" before executing it? :) thanks

도움이 되었습니까?

해결책

I guess you could have a parameter called "confirmation" that requires a specific string (e,g, "I know what I am doing") to be passed in, if it is not set, or is set incorrectly, just return from the procedure without executing the main code. Not exactly what you wanted, but it is an option.

eg - (untested and probably terrible syntax)

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

다른 팁

In short, no.

The theory goes that anybody with permissions to find and be able to run a stored procedure, should be allowed. It would be better to restrict permissions so that those with an excess curiosity do not have the permissions to run this.

The other, less secure, option would be to require a pre-defined secret that needs to be passed as a parameter - of course they could just script the stored procedure off to find the secret though...

Of course, the other point would be: If it's not callable, why include it? After all, when you come to do admin type tasks, you can have the statements scripted off as a file that you can keep secure on your own machine

이를 수행하는 가장 간단한 방법은 2013 년에 새로운 클래식 모드 웹 응용 프로그램을 만드는 것입니다 ( http://technet.microsoft.com/en-us/library/gg276326.aspx ).그런 다음 질문에 언급 한 기사를 사용하여 콘텐츠 데이터베이스를 첨부 한 후 웹 응용 프로그램을 클레임 모드로 변환하십시오.

You can add a @reallyReallyReallyDelete parameter to the sproc which will serve as a safety measure: if it's set to YesYesYes will actually commit the transaction.

You could use a bit input called @UserKnowsWhatTheyAreDoing and check to see if it is true before executing. If it's false, print a friendly message and return gracefully from the procedure

14와 15를 모두 갖는 호환성 레벨에서 실제 이점을 얻는 몇 가지 경우가 있습니다. 사이트에 고스트 파일을 추가하는 솔루션이있는 경우 건강 분석기 경고가 없습니다.14 모드에서만 배포하는 경우 15 개 하이브에 존재합니다.또 다른 인스턴스는 동일한 2010 솔루션에서 2010 및 2013에 대한 사이트 정의를 갖추고 있습니다.

뉴스인가에서 우리는 2013 년에 설치하는 2010 솔루션이 많은 수의 솔루션을 가지고 있습니다. 호환성 울벨을 사용하는 유일한 경우는 우리가 고스트 파일을 가질 때입니다.

Here's yet another approach, which I think is fit for the particular case when a procedure is to be called by a user directly rather than from an application.

I must say, it proposes less trouble for the user while more (maybe, disproportionately) for the developer in comparison with most other suggestions. You decide whether it suits you.

Anyway, here goes.

First, you create a special table, CriticalCalls, to register calls to critical procedures. The table would have a structure like this:

SPID int,
ProcName sysname,
CallTime datetime

Basically, the idea is that a critical SP should be called twice: first it registers its call and informs the user to repeat the call within a certain interval of time as a confirmation of their intention, and with the second call, if made accordingly, it actually proceeds with completing its task.

So the starting part of every critical procedure would have this logic:

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

Actually, I think, it would be best to use a dedicated SP (named CheckCriticalCalls below) for all manipulations with CriticalCalls, including all the necessary modifications. CheckCriticalCalls would receive the name of the procedure to be checked and return a sort of flag showing whether the specified procedure should perform its real operation.

So it might look rather like this:

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

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

The idea behind setting the lower limit of the interval is merely to prevent the user from calling a critical procedure twice automatically, i.e. by executing two identical EXECUTE... lines in one batch. The upper limit, of course, is necessary to 1) ensure that the user confirms their very recent intention to perform the critical operation; 2) prevent execution if the existing record in CriticalCalls is actually left there from a past session with the same SPID.

So, basically, an interval of 1-2 seconds to half a minute would seem quite natural to me. You might pick different figures instead.

Do you need to REALLY delete them from the DB? If I can afford the extra space I'll put a 'Deleted' flag in my tables and a last updated column. This way if a record is accidentally deleted at least I can usually track it down and restore it fairly easily. Just a thought.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top