[英]SQLCLR stored procedures with input parameter
我对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)
我在这里做错了什么?
两个(也许3个)问题:
paramAge.Value = strAirline;
应该:
paramAge.Value = strAirline.Value;
请注意.Value
属性的使用。
WHERE AirlineName = '@strAirline'
(在cmd.CommandText = "...
)应该是:
WHERE AirlineName = @strAirline
注意,单引号已在查询文本中删除。 您只对文字使用单引号,而不对参数/变量使用。
替换以下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()
的调用中设置了“ size”参数。 始终指定最大字符串长度很重要。
随着技术问题的解决,需要解决两个较大的问题:
为什么首先要在SQLCLR中完成此操作? .NET的特定操作尚未完成。 仅仅根据张贴在问题的代码,这将是好得多作为存储过程常规T-SQL。
如果必须保留在SQLCLR中,那么您确实需要将一次性对象包装在using()
构造中,即: SqlConnection
, SqlCommand
和SqlDataReader
。 例如:
using (SqlConnection conn = new SqlConnection("Context Connection=true")) { using (SqlCommand cmd = conn.CreateCommand()) { ... } }
然后您不需要以下两行:
sqldr.Close(); conn.Close();
因为对它们的每个Dispose()
方法的调用都会隐式调用它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.