「あなたは確信している」のためのストアドプロシージャの実行はありますか? :)
-
23-09-2019 - |
質問
私は、削除をたくさんやっているストアドプロシージャを持っています。レコードの数十万人。これは、アプリケーションから実行可能であることを行っていないが、それでも、私は私のクライアントの一つが誤ってそれを実行することを、懸念しています(私は、その「好奇心」に以前の問題を抱えていた):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がヒットしている必要があります。
あなたは安全対策として機能するSPROCに@reallyReallyReallyDelete
パラメータを追加することができます。それはYesYesYes
に設定すると、実際にトランザクションをコミットします。
あなたはそれを実行する前に真であるかどうかを確認するために@UserKnowsWhatTheyAreDoing
とチェックと呼ばれるビットの入力を使用することができます。それが偽なら、優しいメッセージを印刷し、手順から優雅に戻ります。
手順は'Yes I know what I'm doing'
ような特定の値を持つ引数を必要とし得ます。それとも、それは同様の確認や、最近のタイムスタンプを持つ行AN特別なテーブルを探してます。
ここだ、まだ手続きは、ユーザが直接ではなく、アプリケーションから呼び出されるとき、私は思う別のアプローチは、特定の場合に適合している。
私が言わなければならない、それはユーザーにはあまり手間を提案しながら、他のほとんどの提案と比較して、開発者のために(多分、不釣り合い)より。あなたはそれがあなたにぴったりかどうかを決定します。
とにかく、ここに行きます。
まず、あなたは重要な手続きへの呼び出しを登録するには、特別なテーブル、CriticalCalls
を作成します。表は、このような構造を持つことになります:
SPID int,
ProcName sysname,
CallTime datetime
基本的には、アイデアは重要なSPが二度呼ばれるべきであるということである:最初のそれは彼らの意思の確認として、そして2回目の呼び出しで特定の時間間隔内で呼び出しを繰り返して、そのコールと知らせるユーザーを登録し、場合それに応じて作られた、それは実際にそのタスクを完了して進めるます。
だから、すべての重要な手続きの開始部分は、このロジックを持っているでしょう
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
ですべての操作のための専用SP(以下という名前CriticalCalls
)を使用するのがベストでしょう。 CheckCriticalCalls
をチェックするプロシージャの名前を受け取り、指定されたプロシージャは、その本当の操作を実行する必要があるかどうかを示すフラグのようなものを返します。
それはむしろ、このようになります。だからます:
EXECUTE @result = CheckCriticalCalls 'ThisProcedureName';
IF @result = -1 BEGIN
PRINT 'Call me again';
RETURN;
END;
... /* go on with the task */
間隔の下限を設定することの背後にある考え方は、単に、すなわち、1種のバッチ内の2本の同一のEXECUTE...
ラインを実行することにより、自動的に二回クリティカルプロシージャを呼び出すことからユーザーを防止するためです。上限は、当然のことながら、1する必要がある)ユーザーは、重要な操作を実行するには、そのごく最近の意思を確認したことを確認してください。 CriticalCalls
内の既存のレコードは実際には同じSPIDで過去のセッションから残っている場合2)実行を阻止ます。
だから、基本的には、半分分に1〜2秒の間隔は、私にとって非常に自然と思われます。あなたが代わりに別の数字を選ぶかもしれません。
あなたが本当にDBから削除する必要がありますか?私は余分なスペースに余裕があれば、私は私のテーブルの「削除された」フラグと最後に更新された列を入れます。この方法では、レコードが誤って、少なくとも削除された場合、私は通常、それを追跡し、かなり簡単にそれを復元することができます。ただ、考えています。