2017-05-30 21 views
0

を使用してパラメータを取得する方法:私は次のクエリのパラメータを取得するための方法を見つける必要があるテキストコマンド

query = @"declare @p7 int 
      exec some_sproc @[email protected] 
      select @p7"; 

sqlCommand.CommandText = query; 
sqlCommand.CommandType = CommandType.Text; 

IのSQLのparamaterを追加すると疲れが、その後、全体のコードは単にexec sp_executesqlで包み、パラメータが追加されました。これは単に機能しません。あなたはC#側で@ p7の価値をどのように得ることができるか知っていますか?

私のストアドプロシージャは、しかし、デフォルトでは、それは

declare @p11 acco.SomeUDT 
insert into @p11 values(1,'2017-06-15 00:00:00',64.73) 
insert into @p11 values(1,'2017-06-15 00:00:00',1.30) 

に評価され、テーブル値パラメータを使用しています。しかし、私の意図は、構文以下得ることです:私は手動でSQLコードをビルドする理由

declare @p11 acco.SomeUDT 
insert into @p11 values(1,'2017-06-15 00:00:00',64.73), (1,'2017-06-15 00:00:00',1.30) 

これは、 。だから我々は:

query = @"declare @p7 int 

      declare @p11 acco.SomeUDT 
      insert into @p11 values(1,'2017-06-15 00:00:00',64.73), (1,'2017-06-15 00:00:00',1.30) 

      exec some_sproc @[email protected], @[email protected] 
      select @p7"; 
sqlCommand.CommandText = query; 
sqlCommand.CommandType = CommandType.Text; 

私は最初の構文を取得するよりもストアドプロシージャの種類とSQLのパラメータを使用する場合。

すべてが動作しますが、パラメータ@SomeArgもマップする必要があり、問題があります。

+1

プロファイラトレースからのコピー/ペーストのように見える...の.textは、あなたが行っている、sp_executesqlを経由して呼び出します。あなたの質問に詳細を追加して、私が考えている答えを得る必要がある。 –

+1

プロシージャーを実行するためにコマンド・タイプのテキストを使用するという奇妙な要件があるようです。ストアドプロシージャを意図したとおりに使用できないのはなぜですか? –

+0

ADO.NETでテーブル値パラメータを作成して使用することができます。出力パラメータも定義できます。この構文を使用する理由はありません –

答えて

0

あなたは、単にそれがあなたのプロシージャの出力パラメータである場合、また、SQL CommandTextを

query = @"declare @p11 acco.SomeUDT 
      insert into @p11 
      values(1,'2017-06-15 00:00:00',64.73), (1,'2017-06-15 00:00:00',1.30) 
      exec some_sproc @[email protected], @[email protected];"; 

sqlCommand.CommandText = query; 
sqlCommand.CommandType = CommandType.Text; 
sqlCommand.Parameters.Add("@p7", SqlDbType.Int).Direction = ParameterDirection.Output; 
sqlCommand.ExecuteNonQuery(); 

Console.WriteLine(sqlCommand.Parameters["@p7"].Value); 

にパラメータとして、それを追加する代わりに、クエリ内の@ P7を宣言しますが、ないことによってこれを行うことができるはずあなたはおそらく使用する必要があります。

exec some_sproc @[email protected] OUT, @[email protected]; 
          ^^^ 

EDIT

をあなたはボビートンに関するいかなる懸念がある場合ABLES、変換の問題や、それがこのようなSQL文字列を構築するために、悪い考えですなぜ、あなた C#でテーブルを作成し、あまりにも、それをパラメータとして渡すことができ、すべての理由:

var table = new DataTable(); 
// TODO: Add the correct column names for your TVP here 
table.Columns.Add("Column1", typeof(int)); 
table.Columns.Add("Column2", typeof(DateTime)); 
table.Columns.Add("Column3", typeof(decimal)); 

table.Rows.Add(1, new DateTime(2017, 6, 15), 64.73); 
table.Rows.Add(1, new DateTime(2017, 6, 15), 1.3); 

sqlCommand.CommandText = "some_sproc"; 
sqlCommand.CommandType = CommandType.StoredProcedure; 
sqlCommand.Parameters.Add("@SomeArg", SqlDbType.Int).Direction = ParameterDirection.Output; 

var tvp = sqlCommand.Parameters.Add("@SomeUDTArg", SqlDbType.Structured); 
tvp.TypeName = "acco.SomeUDT"; 
tvp.Value = table; 

sqlCommand.ExecuteNonQuery(); 

Console.WriteLine(sqlCommand.Parameters["@SomeArg"].Value); 
+0

テーブル値パラメータをADO.NETパラメータとして渡すのはなぜですか? –

+0

これは質問に必要であることを示唆するものは何もないので。 c#で表を作成して、それをパラメータとして渡すのはもっと努力ですが、値がC#から来ない場合は、この余計な作業には何の意味もありません。 – GarethD

+0

Bobbyのテーブル、変換の問題、またはこのようなSQL文字列を作成することが悪い考えがある理由はどうですか? –

0

このストアドプロシージャを使用していますテーブル値のパラメータを入力として使用し、出力パラメータを入力します。スクリプトのTVPを埋める理由はありません。あなたはクライアント側でそれを記入することができます。

実際、これはTVPを使用する主な利点の1つでした。サーバー側でTVPを構築すると、それを放棄します。

sqlCommand.CommandText = "some_sproc"; 
sqlCommand.CommandType = CommandType.StoredProcedure; 

//Create the out parameter 
var outParam=sqlCommand.Parameters.Add("@SomeArg", SqlDbType.Int); 
outParam.Direction = ParameterDirection.Output; 

//Set the TVP value 
var tvpParam=sqlCommand.Parameters.Add("@SomeUDTArg",SqlDbType.Structured); 
tvpParam.Value=myTable; 

//Run it 
sqlCommand.ExecuteNonQuery(); 


//And read the results 
var result=outParam.Value; 

myTable強く型付けされたDataTableまたは実行時に作成されたDataTableをすることができます。

public class MyRecord 
{ 
    public int ID{get;set;} 
    public DateTime Date {get;set;} 
    public decimal Value {get;set;} 
    public MyRecord(int id,DateTime date,decimal value){....} 
} 

var myValues=new List<MyRecord> 
      { 
       new MyRecord(1,new DateTime(2017,6,15),64.73m), 
       new MyRecord(1,new DateTime(2017,6,15),1.39m) 
      }; 

var myTable=myValues.ToDataTable(); 

のフィールド名の場合...:私は強く型付けされたコレクションからのDataTableを作成するためにMoreLinqパッケージからToDataTable拡張メソッドを使用しますので、私は怠け者クラスが一致するUDTとプロパティ名を指定すると、他の変更は必要ありません。

レコードのセットをデフォルトのTVP値として使用する場合は、一度作成して、たとえば静的または遅延初期化フィールドに格納することができます。この方法では、あなたが他のパラメータが提供されていない場合は、デフォルト値を用いる方法で作成できます

void DoSomething(IEnumerable<MyRecord> records) 
{ 
    ... 
    //Set the TVP value 
    var tvpParam=sqlCommand.Parameters.Add("@SomeUDTArg",SqlDbType.Structured); 

    tvpParam.Value=(records==null)?DefaultValues:records.ToDataTable(); 

    //Run it 
    sqlCommand.ExecuteNonQuery(); 

    ... 

} 
関連する問題