2016-04-04 95 views
0

我對SQLCLR存儲過程頗爲陌生。在我的例子中,我有兩個存儲過程,一個沒有參數,另一個有輸入參數。兩個目標都是相同的表格。具有輸入參數的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存儲過程?它看起來並不像你在做任何CLR比原生T-SQL特效更好的事情。所以,你沒有任何好處會導致開銷。 –

+0

你是對的,這只是一個練習來學習正確的語法。 – user2371684

回答

0

兩個(也許3)問題:

  1. paramAge.Value = strAirline;應該是:

    paramAge.Value = strAirline.Value;

    注意使用.Value財產。

  2. WHERE AirlineName = '@strAirline'(內cmd.CommandText = "...)應爲:

    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()總是指定最大字符串長度很重要。

隨着技術問題的出路,有兩個較大的問題需要解決:

  1. 這是爲什麼正在做SQLCLR擺在首位?沒有任何具體的.NET正在完成。完全基於問題中發佈的代碼,這將是更多的作爲常規T-SQL存儲過程。

  2. 如果必須留在SQLCLR,那麼你真的需要來包裝using()結構,即一次性對象:SqlConnectionSqlCommandSqlDataReader。例如:

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

    ,然後你不需要以下兩行:

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

    因爲他們將通過調用他們的每一個Dispose()方法隱式調用。

+0

謝謝你,幫忙:)真的,這不是一個正確使用clr存儲過程,只是嘗試這個練習,我會稍後進行並添加一些業務邏輯。 再次感謝:) – user2371684