2011-04-08 13 views
5

私たちには10-12歳の古いプロジェクトがあります。それはSQL2008に移行したSQL2000を使用していました。ストアドプロシージャの動的作成SQLは、ストアドプロシージャの目的を否定しますか?

この作業では、ストアドプロシージャがパラメータを受け入れていて、クエリを文字列として構築してから、EXECを使用してコマンドを実行していることがわかりました。

CREATE PROCEDURE MyProc 
    (@TableName varchar(255), 
    @FirstName varchar(50), 
    @LastName varchar(50)) 
AS 

    -- Create a variable @SQLStatement 
    DECLARE @SQLStatement varchar(255) 

    -- Enter the dynamic SQL statement into the 
    -- variable @SQLStatement 
    SELECT @SQLStatement = "SELECT * FROM " + 
        @TableName + "WHERE FirstName = '" 
        + @FirstName + "' AND LastName = '" 
        + @LastName + "'" 

    -- Execute the SQL statement 
    EXEC(@SQLStatement) 

これは悪いアプローチですか。これにより、ストアドプロシージャ(プリコンパイルされたクエリの利点)の利点が失われますか?

+0

このようにしてselectを行うのは、唯一の目的であれば、悪い考えですが、パフォーマンス上の理由からではなくデザインが悪いからです。 – JNK

+0

+1質問には、これは単なる例であり、一般的な質問であると理解しています。これはストアドプロシージャの利点を殺しますか?より複雑なsprocで言えましょう。 –

+0

はい、SPは単なる例ですが、私が心配しているものは本当に大きくて醜いです...彼らは次のようなパターンを持っています。つまり、中間のSELECT文を作成し、ページ区切りなど... –

答えて

7

いいえ、私は、ストアドプロシージャの主な利点は、もはやそれが "あらかじめコンパイルされた"という事実ではないと主張するでしょう(2005年以前から、おそらくは非常に大量の呼び出しを除いて)。

アドホック・ステートメントでも使用できるプラン・キャッシュがあります。テーブル名をパラメータ化されたため

CREATE PROCEDURE MyProc 
    (@FirstName varchar(50), 
    @LastName varchar(50)) 
AS 
BEGIN 
    SELECT * FROM TABLENAME 
    WHERE FirstName = @FirstName 
     AND LastName = @LastName 
END 

全て:

この特定の例では、と自動であろう注射に対する脆弱性を再導入しました。

ストアドプロシージャの利点には、実行します。

  • セキュリティ管理(独立SELECT/INSERT/UPDATEのEXEC権利を制御することができる)

  • アクセスコーディネーション(すべての動作を保証することは、特定の中で行われています方法)

  • 組織(一貫した方法でデータベースへのインターフェイスを構成することができます)

  • 注入防止(ストアドプロシージャは常にパラメータ化されています。これにより、呼び出し側が注射の脆弱性を持つデータベースケースを作成できなくなります.SP自体は正しく書かれている必要がありますが、クライアントプログラマは、 )のSPとしないテーブルへのアクセス権を持っている

  • システムインベントリ(名によって特定の手順をプロファイルし、最適化することができる、ストアドプロシージャで構成された包括的かつ十分に立証界面層を有することができること)

のみ

SPの動的SQLはその場所があり、セキュリティのようなものを無効にすることができますそれは新しいチェーンを開始するので、ここでSELECT権限を与える必要があります)と注入。実行プランのキャッシングは、私がリストに載せたものではありません。

0

実行計画の複雑さによって異なります。この特定のケースでは、実行計画が非常に単純になるため、ストアドプロシージャに問題はありません。

1

EXEC(@SQL)の代わりにsp_execute(@SQL)を試してください。

sp_execute(@SQL)は、クエリプランの再利用を促進します。 sp_executesqlを使用する場合、ユーザーまたはアプリケーションが明示的にパラメータを識別します。このテクニック記事のプランキャッシングの問題hereについては、#3を参照してください。

+0

また、sp_executesqlの落とし穴について説明するこの記事をお勧めします。http://www.sqlskills.com/BLOGS/KIMBERLY/post/EXEC-and-sp_executesql-how-are-they-different.aspx –

1

「ストアドプロシージャの目的」とみなされる内容によって異なります。私は、データベースにセキュリティ保護可能なAPIを公開し、アプリケーションをデータベース実装から分離するために、SQLをコードベースから除外することによってストアドプロシージャが存在すると主張します。

このようにすると、データベースを参照するアプリケーションコードとは独立に変更およびバージョン管理できる独立したコンポーネントになります(APIシグネチャが変更されない限り)。

ストアドプロシージャの引数と結果セットが変更されない限り、データベースアクセスがストアドプロシージャ経由で行われている場合、DBAは問合せをチューニングし、dbをハートの内容に自由に変更できますコードがデータモデルに関して行う前提を打ち破ります。コードの変更を必要とせずに基本的なスキーマを完全に変更することができます。

これはストアドプロシージャの真の利点です。

関連する問題