2016-04-04 10 views
0

SQLCLRストアドプロシージャの新機能です。私の例では、2つのストアドプロシージャがあり、1つはパラメータなしで、もう1つは入力パラメータ付きです。どちらも同じテーブルを対象としています。入力パラメータを持つSQLCLRストアドプロシージャ

パラメータのないものは正常に動作し、結果のすべての行を返します。しかし、同じテーブルを対象とした入力パラメータを持つものは、エラーが発生していなくても行が返されません。 .NETコードの入力パラメータはSqlStringに設定され、データベースにはNVARCHAR(50)が設定されています。

これは私のC#のコードがどのように見えるかです:

using System; 
using System.Data; 
using System.Data.SqlClient; 
using System.Data.SqlTypes; 
using Microsoft.SqlServer.Server; 

public partial class StoredProcedures 
{ 
    [Microsoft.SqlServer.Server.SqlProcedure] 
    public static void AirlineSqlStoredProcedure (SqlString strAirline) 
    { 
     SqlConnection conn = new SqlConnection(); 
     conn.ConnectionString = "Context Connection=true"; 

     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = conn; 
     conn.Open(); 
     cmd.CommandText = "SELECT dbo.tblAirline.AirlineName, dbo.tblAircraft.AircraftUnits, dbo.tblAircraft.Manufacturer, dbo.tblAircraft.AircraftModel FROM dbo.tblAircraft INNER JOIN dbo.tblAirline ON dbo.tblAircraft.AirlineID = dbo.tblAirline.AirlineID WHERE AirlineName = '@strAirline' ORDER BY dbo.tblAircraft.AircraftUnits DESC"; 
     SqlParameter paramAge = new SqlParameter(); 
     paramAge.Value = strAirline; 
     paramAge.Direction = ParameterDirection.Input; 
     paramAge.SqlDbType = SqlDbType.NVarChar; 
     paramAge.ParameterName = "@strAirline"; 

     cmd.Parameters.Add(paramAge); 
     SqlDataReader sqldr = cmd.ExecuteReader(); 
     SqlContext.Pipe.Send(sqldr); 

     sqldr.Close(); 
     conn.Close(); 
    } 

    [Microsoft.SqlServer.Server.SqlProcedure] 
    public static void AirlineAircraftStoredProcedure() 
    { 
     //It returns rows from Roles table  
     SqlConnection conn = new SqlConnection(); 
     conn.ConnectionString = "Context Connection=true"; 

     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = conn; 
     cmd.CommandText = "SELECT dbo.tblAirline.AirlineName, dbo.tblAircraft.AircraftUnits, dbo.tblAircraft.Manufacturer, dbo.tblAircraft.AircraftModel FROM dbo.tblAircraft INNER JOIN dbo.tblAirline ON dbo.tblAircraft.AirlineID = dbo.tblAirline.AirlineID ORDER BY dbo.tblAircraft.AircraftUnits DESC"; 
     conn.Open(); 

     SqlDataReader sqldr = cmd.ExecuteReader(); 
     SqlContext.Pipe.Send(sqldr); 

     sqldr.Close(); 
     conn.Close(); 

    } 
} 

そして、私は、ストアドプロシージャを実行するとき、私は空の行を取得:また

USE [TravelSight] 
GO 

DECLARE @return_value Int 

EXEC @return_value = [dbo].[AirlineSqlStoredProcedure] 
     @strAirline = N'American Airlines' 

SELECT @return_value as 'Return Value' 

GO 

(0 row(s) affected) 

(1 row(s) affected) 

を、入力パラメータのために、私は前にNを置きます文字列。

同じテーブルを対象に、ストアドプロシージャAirlineAircraftStoredProcedureを実行しているとき、私は戻って、すべての行取得しています:

USE [TravelSight] 
GO 

DECLARE @return_value Int 

EXEC @return_value = [dbo].[AirlineAircraftStoredProcedure] 

SELECT @return_value as 'Return Value' 

GO 


(8 row(s) affected) 


(1 row(s) affected) 

を、私はここで間違って何をしましたか?

+0

これは単なる例ではありますが、そうでない場合は、なぜこれらのCLRストアドプロシージャですか?ネイティブのT-SQLプロキシよりもCLRが特に優れているようなことはしていません。したがって、あなたは利益のためにオーバーヘッドを負っています。 –

+0

あなたは正しいです、これは適切な構文を学ぶための単なる練習です。 – user2371684

答えて

0

つ(多分3)問題:

  1. paramAge.Value = strAirline;は次のようになります。

    paramAge.Value = strAirline.Value;

    .Value財産の使用を注意してください。 (cmd.CommandText = "...以内)

  2. WHERE AirlineName = '@strAirline'する必要があります:単一引用符がクエリテキストに削除されたことを

    WHERE AirlineName = @strAirline

    注意してください。リテラルに対しては単一引用符を使用し、パラメータ/変数は使用しません。

  3. は、以下の5行を置き換えます

    SqlParameter paramAge = new SqlParameter(); 
    paramAge.Value = strAirline; 
    paramAge.Direction = ParameterDirection.Input; 
    paramAge.SqlDbType = SqlDbType.NVarChar; 
    paramAge.ParameterName = "@strAirline"; 
    

    で:

    SqlParameter paramAge = new SqlParameter("@strAirline", SqlDbType.NVarChar, 50); 
    paramAge.Direction = ParameterDirection.Input; // optional as it is the default 
    paramAge.Value = strAirline.Value; 
    

    は、 "サイズ" パラメータがnew SqlParameter()への呼び出しで設定されたことに注意してください。 は常にで、最大文字列長を指定することが重要です。道のうち技術的な問題に

、アドレスには2つの大きな問題があります。これは最初の場所でSQLCLRで行われているのはなぜ

  1. は? .NET固有のものは何も実行されていません。質問に掲示されたコードだけに基づいて、多くの通常のT-SQLストアドプロシージャとして良いでしょう。SqlConnectionSqlCommand、およびSqlDataReader:それはSQLCLRに残っている必要がある場合は

  2. 、あなたが本当にusing()すなわち構造、使い捨てのオブジェクトをラップする必要があります。たとえば、次のように

    using (SqlConnection conn = new SqlConnection("Context Connection=true")) 
    { 
        using (SqlCommand cmd = conn.CreateCommand()) 
        { 
        ... 
        } 
    } 
    

    、その後、あなたは次の2行は必要ありません:彼らは彼らのDispose()の各メソッドの呼び出しによって暗黙的に呼び出されるよう

    sqldr.Close(); 
    conn.Close(); 
    

    を。

+0

ありがとうございました:)これは、clrストアドプロシージャを適切に使用することではなく、これをエクササイズとして試してみてください。後で説明し、ビジネスロジックを追加します。 ありがとうもう一度:) – user2371684