2009-08-31 8 views
1

私のアプリケーションには一般的な「SQLに保存」メソッドであるはずの次のメソッドがあります。私のストアドプロシージャを使用する際のトラブル

protected void EjecutarGuardar(string ProcedimientoAlmacenado, object[] Parametros) 
     { 
      SqlConnection Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 

      SqlCommand Command = Connection.CreateCommand();    
      Command.CommandType = CommandType.StoredProcedure; 
      foreach (object X in Parametros) 
      { 
       Command.Parameters.Add(X); 
      }    

      Connection.Open(); 
      Command.ExecuteNonQuery(); 
      Connection.Close(); 

      Connection.Dispose(); 
     } 

StoredProcedureのNAMEとパラメータでいっぱいの配列を渡す必要があります。私はこの時点で一種迷っています。ストアドプロシージャ「ProcedureimientoAlmacenado」のNAMEはどこで使用しますか?

私はおそらくCommand.Command ????? somecignと思っていますか?しかし、私はそこで失われています。どんな助け?

編集簡単に言うと、私のデータベースに「ABC」という名前のストアドプロシージャがあります。私のコードでSqlCommand "Command"にどのように関連付けることができますか?

答えて

3

Command.CommandText= ProcedimientoAlmacenado

パラメータは、あまりにも名前を持っている必要があります。 Parametros配列にはSqlParameterオブジェクトまたは汎用のC#オブジェクトが含まれていますか?

パラメータは、一般的なC#のオブジェクトである場合は、名前と値の辞書に渡す方が良いです:

protected void EjecutarGuardar(string ProcedimientoAlmacenado, 
    Dictionary<string, object> Parametros) 
{ 
    using (SqlConnection Connection = new SqlConnection(...)) 
    { 
     Connection.Open(); 
     SqlCommand Command = Connection.CreateCommand() 
     Command.CommandText = ProcedimientoAlmacenado; 
     Command.Connection = Connection;  
     Command.CommandType = CommandType.StoredProcedure; 
     foreach (string name in Parametros.Keys) 
     { 
      Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value); 
     }    
     Command.ExecuteNonQuery(); 
    } 
} 

これは、迅速かつ汚いアプローチです。 AddWithValueは、VARCHARではなく文字列にNVARCHAR型のパラメータを渡します。アドホックSQLでは、VARCHAR型の列でSARGの問題が発生する可能性があるため(変換は常にVARCHAR NVARCHARへと変換します)。ただし、ストアド・プロシージャではプロシージャに型パラメータがあるため、プロシージャがパラメータ型VARCHARで作成されている場合は強制変換がVARCHARに発生するため、このような問題はありません。高性能システムで

Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value); 

このアプローチは、実行を汚染:あなたのような何かをする必要がありますので、

ます。また、NULLパラメータを渡すの周りに問題がありますが、パラメータがDBNull.ValueはないnullなければなりませんAddWithValueはNVARCHAR(<length of the database type>)ではなく、NVARCHAR(<exact length of the string>)の型のパラメーターを渡すため、不必要なキャッシュが発生します。したがって、Paramaters.AddWithValue("@name", "John")Parameters.AddwithValue("@name", "Doe")は、NVARCHAR(4)型のパラメータで呼び出され、NVARCHAR(3)パラメータで呼び出され、SQL計画キャッシュで異なる型と表示されるため、キャッシュに2つの異なる計画を作成します。これは単純なプロジェクトでは問題にはなりませんが、より複雑で高性能なプロジェクトでは、パラメータ型を明示的に設定することをお勧めします。

私は、この種の汎用的なワンサイズ対応のプロシージャを避け、適切なタイプのパラメータを使用して、各データベースプロシージャに対して明示的なC#ラッパーを持つデータアクセスレイヤを作成することをお勧めします。厳密に型指定されたデータセットは実際にこれを行うことができます。私の好きなやり方は、C#ラッパーを作成するXSLTスタイルシートを使用してXMLファイルからデータアクセススライダー全体を生成することです。ソースXMLはもちろん、データベースのメタデータ自体から抽出されます。

+0

彼らはただ一般的なオブジェクトです。私の計画は、オブジェクト(int、string、bool)の束をobject []配列にロードし、foreachを使用してパラメータをロードすることです。これはうまくいくでしょうか? :) –

+0

いいえ、パラメータ名の値の辞書を渡し、各パラメータの名前を割り当てる必要があります。 –

+0

ストアドプロシージャは、コマンドオブジェクトに追加できるパラメータを指定します。 –

0
Command.ComandText = "storedProcName"; 
0

Command.CommandText = "ProcedimientoAlmacenado";Command.CommandType = CommandType.StoredProcedure;前または後にこれは必須ではありませんが、それは私がそれを行う方法です。

0

は、ストアドプロシージャの名前にSqlCommandオブジェクトのCommandTextプロパティを設定します。

Command.CommandText = "MyStoredProcedureName"; 
関連する問題