检查变量是否存在..inline sql

时间:2016-11-11 16:48:11

标签: c# sql-server

SQL Server 2016 .Net 4.5.2 C#

我尊重地说,我正在使用Northwind数据库来展示我想要实现的目标。请不要评论Northwind数据库。这只是我将要做的一个例子。

我正在使用ADO.Net来执行内联sql。我的困境是我将有可能传递给sql查询的可选参数。这是C#:

var city = "";
var state = "tx";
var sqlQuery = "
       if exists @City
       begin
       select * from Customers where city = @City and state=@State;
       end
       else
       begin
        select * from Customers where state=@State;
       end
    ";

var conn =  new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand(sqlQuery, conn);

if (!string.IsNullorEmpty(city))
{
    SqlParameter param  = new SqlParameter();
    param.ParameterName = "@City";
    param.Value         = city;
    cmd.Parameters.Add(param);
}   

if (!string.IsNullorEmpty(state))
{
    SqlParameter param  = new SqlParameter();
    param.ParameterName = "@State";
    param.Value         = state;
    cmd.Parameters.Add(param);
}

var reader = cmd.ExecuteReader();

如您所见,变量city为空,因此参数@City不会传递给sql查询,但变量状态不为空,因此@State参数将传递给查询。请记住,@ City不会一直空白。我在sql中检查是否存在@City,但这不起作用。如果@City,@ State或可能传入的任何其他参数存在,我如何检查sql查询?如果我可以想出那个部分,我可以处理sql中需要做的事情。感谢您的帮助。

P.S。我不能使用存储过程。

2 个答案:

答案 0 :(得分:2)

select *
from
    Customers
where
    state=@State
    AND (city = @City
       OR ISNULL(@City,'') = '')

我建议上面你可以在1选择语句中完成,而不必使用IF控制方法。它将测试城市,但它也会说@City是否为空,然后返回它,因为只有其中一个条件可以是真的,你永远不会得到你不想要的结果。要使用控制方法,您可以执行以下操作,

IF ISNULL(@City,'') <> ''
BEGIN
    select * from Customers where city = @City and state=@State;
END
ELSE
BEGIN
    select * from Customers where state=@State;
END

但是第一个例子再次更标准,代码更少,所以我建议这样做。

编辑: 您必须每次都传递参数。否则,您实际上将更改C#代码中的SQL语句而不是SQL代码。

接下来,您将实际传递一个空字符串而不是NULL值,查看您的var city = "";分配,以便您可以切换到测试。

完全没有传递参数的问题是你的SQL语句将使用你没有声明的变量,如果你不添加参数值。因此标准方法是始终传递变量并使用类似上面第一个的SQL语句。如果您真的想以不同的方式完成它甚至根本不通过,那么您将需要使用c#控制流来不同地构建SQL字符串。

标准方式:

var city = "";
var state = "tx";
var sqlQuery = "
    select *
    from
        Customers
    where
        state=@State
        AND (city = @City
            OR ISNULL(@City,'') = '')
";

var conn =  new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
conn.Open();

SqlCommand cmd = new SqlCommand(sqlQuery, conn);

SqlParameter param  = new SqlParameter();
param.ParameterName = "@City";
param.Value         = city;
cmd.Parameters.Add(param);

SqlParameter param  = new SqlParameter();
param.ParameterName = "@State";
param.Value         = state;
cmd.Parameters.Add(param);

var reader = cmd.ExecuteReader();

不传递参数的方法是通过c#控制流动态构建SQL语句:

var city = "";
var state = "tx";
var sqlQuery = "
    select *
    from
        Customers
    where
        state=@State
";

if (!string.IsNullorEmpty(city))
{
    sqlQuery += "
            AND city=@City";
}

var conn =  new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
conn.Open();

SqlCommand cmd = new SqlCommand(sqlQuery, conn);

if (!string.IsNullorEmpty(city))
{
    SqlParameter param  = new SqlParameter();
    param.ParameterName = "@City";
    param.Value         = city;
    cmd.Parameters.Add(param);
}

SqlParameter param  = new SqlParameter();
param.ParameterName = "@State";
param.Value         = state;
cmd.Parameters.Add(param);

var reader = cmd.ExecuteReader();

如果你没有通过参数,那么为了更加了解must declare scalar variable @city的原因是因为c#中的参数定义是在SQL中定义变量的内容。所以:

SqlParameter param  = new SqlParameter();
param.ParameterName = "@City";
param.Value         = city;
cmd.Parameters.Add(param);

基本上在SQL中这样做:

DECLARE @City VARCHAR(50)
SET @City = value of city var.

因此,如果您在城市变量上使用if控制流而忽略此步骤,则省略变量定义,SQL将失败。因此,虽然参数的值可以是可选的,但如果在SQL语句中引用它,则参数本身不是选项。

另请注意,您在参数定义中使用隐式数据类型,您应该明确定义数据类型!

答案 1 :(得分:0)

当您通过sql进行传递时,使用可选参数很有挑战性。它确实无助于使您的代码更好。选项参数在存储过程中很有用,但在传递查询中,它比它的价值要大得多。处理此问题的最佳方法是始终传递参数。但是你可以传递一个DBNull并在你的查询中处理它。

我还强烈建议您开始在USING语句中包装iDisposable对象。特别是连接和命令之类的东西。您不希望软管连接池,因为您偶然错过了Dispose通话。

这是一种可以非常干净地管理这类事物的方法。

var sqlQuery = "select *
from Customers
where 
(
    state = @State
    OR
    @state is null
)
AND
(
    city = @City
    OR
    @City is null
)";

using (SqlConnection conn =  new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI"))
{
    conn.Open();
    using(SqlCommand cmd = new SqlCommand(sqlQuery, conn))
    {
        SqlParameter param  = new SqlParameter();
        param.ParameterName = "@City";
        if (string.IsNullorEmpty(city))
        {
            param.value = DBNull.Vale;
        }
        else
        {
            param.Value = city;
        }
        cmd.Parameters.Add(param);

        SqlParameter param  = new SqlParameter();
        param.ParameterName = "@State";
        if(string.IsNullorEmpty(state))
        {
            param.value = DBNull.Vale;
        }
        else
        {
            param.Value = state;
        }
        cmd.Parameters.Add(param);
       }

    }
}