2017-09-07 10 views
0

SQL Server用のストアドプロシージャを作成して、C#アプリケーションから呼び出します。ストアドプロシージャには、クエリでsp_executesqlを実行するパラメータを受け取る動的に作成されたSQLがいくつか含まれていますが、C#アプリケーションから実行すると結果が得られません。C#ストアドプロシージャの動的パラメータの使用

SQL Server Management Studioからプロシージャを呼び出すと、すべての結果が得られます。例えば

EXECUTE proc_getproductslist '''1'',''2''' 

この作品:私はSSMSで実行した場合、私は私のストアドプロシージャ

CREATE PROCEDURE [dbo].[proc_getproductslist] 
    @idProducts varchar(max) 
AS 
BEGIN 

    DECLARE @SQL nvarchar(max) 

    SET @SQL = 'SELECT * FROM Products WHERE id IN ('[email protected] +')' 

    EXEC sp_executesql @SQL 
END 

を作成

id | Descrip 
1 Pen 
2 Pencil 
3 Table 

私のテーブルの製品を入手!私は、これは何も返さない私のC#のアプリからストアドプロシージャを呼び出すと

DataTable dt = new DataTable(); 
DataTable d1 = new DataTable(); 

using (SqlConnection cn = new SqlConnection("cnxstring")) 
{ 
    cn.Open(); 

    SqlCommand cmd1 = new SqlCommand("proc_getproductslist", cn, sqlTran); 
    cmd1.CommandType = CommandType.StoredProcedure; 

    try 
    { 
     cmd1.Parameters.Add("@numguia", SqlDbType.VarChar).Value = "'''1'',''2'''"; 

     SqlDataAdapter da1 = new SqlDataAdapter(); 
     da1.SelectCommand = cmd1; 
     da1.Fill(d1); 
    } 
    catch (SqlException exsql) 
    { 
     try 
     { 
      sqlTran.Rollback(); 
     } 
     catch (Exception exRollback) 
     { 
     } 
    } 
    catch (Exception ex) 
    { 
    } 
    finally 
    { 
     cn.Close(); 
    } 

    return d1; 
} 

:しかし... C#のアプリから、これは

C#のコードを動作しません。

私はこの作業を行う方法を教えてください。

おかげCommandType = CommandType.StoredProcedureとSelectコマンドのあなたのC#コードパラメータの名前で

+0

最後に、(簡潔にするためのtry/catchを削除)あなたのプロシージャを呼び出すには? –

答えて

0

TSQLの 'がエスケープされています'。 C#ではそうではありません。そして最初と最後は文字列リテラルを示す。 int型

cmd1.Parameters.Add("@numguia", SqlDbType.VarChar).Value = "1,2"; 

EGのリストのように見えるので、C#の "始まりではと文字列リテラルを終了。

ので

cmd1.Parameters.Add("@numguia", SqlDbType.VarChar).Value = "'''1'',''2'''"; 

cmd1.Parameters.Add("@numguia", SqlDbType.VarChar).Value = "'1','2'"; 

かであるべき

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.SqlClient; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApp10 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var con = new SqlConnection("Server=localhost;database=tempdb;integrated security=true")) 
      { 
       con.Open(); 

       var ddl = new SqlCommand(@" 
CREATE OR ALTER PROCEDURE [dbo].[proc_getproductslist] 
    @idProducts varchar(max) 
AS 
BEGIN 

    DECLARE @SQL nvarchar(max) 

    SET @SQL = 'SELECT ''success'' result WHERE ''1'' IN ('[email protected] +')' 

    EXEC sp_executesql @SQL 
END 
", con); 
       ddl.ExecuteNonQuery(); 

       var cmd = new SqlCommand("proc_getproductslist", con); 
       cmd.CommandType = System.Data.CommandType.StoredProcedure; 

       cmd.Parameters.Add("@idProducts", SqlDbType.VarChar).Value = "'''1'',''2'''"; 


       var result = (string)cmd.ExecuteScalar() ; 
       Console.WriteLine(result??"null"); 

       cmd.Parameters["@idProducts"].Value = "'1','2'"; 
       result = (string)cmd.ExecuteScalar(); 

       Console.WriteLine(result??null); 

       Console.ReadKey(); 

      } 
     } 
    } 
} 

出力

null 
success 
2

は、SQLコードで定義されたパラメータの名前と一致する必要があります。お試しください

cmd1.Parameters.Add("@idProducts", SqlDbType.VarChar).Value = "1,2"; 
2

理由だけで、これは、彼らがために設計された、まさにかなり多くあり、テーブル大切偶然には使用しないで...

まずあなたのタイプを作成します。次に

CREATE TYPE dbo.ListOfInt AS TABLE (Value INT NOT NULL); 

あなたを手続きは簡単です。

CREATE PROCEDURE [dbo].[proc_getproductslist] @idProducts dbo.ListOfInt READONLY 
AS 
BEGIN 
    SELECT * 
    FROM Products 
    WHERE id IN (SELECT Value FROM @idProducts); 

END 

動的SQLは必要ありません。早急に、it is not good idea to use SELECT * in production code。なぜあなたは標準的なパラメータを使用していない

DataTable dt = new DataTable(); 
DataTable d1 = new DataTable(); 

//Set the IDs you wish to pass 
DataTable dtParam = new DataTable(); 
dtParam.Columns.Add("Value", typeof(int)); 
dtParam.Rows.Add(1); 
dtParam.Rows.Add(2); 


using (SqlConnection cn = new SqlConnection("cnxstring")) 
using (SqlCommand cmd1 = new SqlCommand("proc_getproductslist", cn, sqlTran)) 
{ 
    cn.Open(); 
    cmd1.CommandType = CommandType.StoredProcedure; 

    //Create and add the parameter 
    var tableParam = new SqlParameter("@numguia", SqlDbType.Structured); 
    tableParam.Value = dtParam; 
    tableParam.TypeName = "dbo.ListOfInt"; 
    cmd1.Parameters.Add(tableParam); 

    SqlDataAdapter da1 = new SqlDataAdapter(cmd1); 
    da1.Fill(d1); 
} 
関連する問題