C# 使用关键字between和order构建动态sql查询

C# 使用关键字between和order构建动态sql查询,c#,sql,sql-server-2008,C#,Sql,Sql Server 2008,我遇到的情况是,sql查询的参数是动态的。如果参数为null,我不想将其添加到查询中,我尝试了一些从未奏效的方法。现在我觉得它像个傻瓜 ds = SqlHelper.ExecuteDataset(GlobalSettings.DbDSN, CommandType.Text, "SELECT TOP 1000 [ID],[Project],[Owner],[Consultant],[Contractor],[Value],[Level1],[Level2] ,[Status] ,[Catego

我遇到的情况是,sql查询的参数是动态的。如果参数为null,我不想将其添加到查询中,我尝试了一些从未奏效的方法。现在我觉得它像个傻瓜

  ds = SqlHelper.ExecuteDataset(GlobalSettings.DbDSN, CommandType.Text, "SELECT TOP 1000 [ID],[Project],[Owner],[Consultant],[Contractor],[Value],[Level1],[Level2] ,[Status] ,[Category]  ,[Country],[CreatedDate],[CreatedByID],[CreatedByName] FROM [tbl_Projects] where"+if(!string.IsNullOrEmpty(paraCategory)){ "[Category] = @Category  and"}+"+ Country =@country and "+if(!string.IsNullOrEmpty(paraCategory)){ " value between @val1 and @val2"}+" order by CreatedDate asc",
                                     new SqlParameter("@Category", paraCategory),
                                      new SqlParameter("@Country", paraCountry),
                                       new SqlParameter("@val1", paraValue1),
                                                        new SqlParameter("@val2", paraValue2));
我还检查了构建动态sql
但在我需要在关键词之间加上“喜欢”和“喜欢”是没有用的。有人能帮我一下吗?

为了给你一个想法,我会这样做:

var sql as new StringBuilder();
sql.Append("SELECT ... all your columns ... FROM yourTable");
var parameters as new List(Of SqlParameter);
if (!string.IsNullOrEmpty(paraCategory)
{
  sql.Append("[Category]=@Category,");
  parameters.AddWithvalue("@Category", paraCategory);
}
sql.Length -= 1

//...your other parameters...

sql.Append("ORDER BY CreatedDate");
然后将其全部传递给SqlHelper:

ds = SqlHelper.ExecuteDataset(GlobalSettings.DbDSN, CommandType.Text, sql.ToString(), parameters);

还要注意,上面的代码并不是真正的防御代码。例如,如果没有传递任何参数,它将失败。由于我不知道SqlHelper类,您可能需要一个SqlParameter列表以外的东西。

为了给您一个想法,我会这样做:

var sql as new StringBuilder();
sql.Append("SELECT ... all your columns ... FROM yourTable");
var parameters as new List(Of SqlParameter);
if (!string.IsNullOrEmpty(paraCategory)
{
  sql.Append("[Category]=@Category,");
  parameters.AddWithvalue("@Category", paraCategory);
}
sql.Length -= 1

//...your other parameters...

sql.Append("ORDER BY CreatedDate");
然后将其全部传递给SqlHelper:

ds = SqlHelper.ExecuteDataset(GlobalSettings.DbDSN, CommandType.Text, sql.ToString(), parameters);
还要注意,上面的代码并不是真正的防御代码。例如,如果没有传递任何参数,它将失败。由于我不知道SqlHelper类,您可能需要使用SqlParameter列表以外的其他内容。

更改SqlHelper.ExecutedataSets,以便委托调用所需的特定代码:

class SqlHelper
{
    public delegate void SqlCommandDelegate(SqlCommand command);

    public Dataset ExecuteDataset(string dsn, 
            CommandType commandType, 
            SqlCommandDelegate specificPreparations)
    {
        Dataset results;
        using (SqlConnection conn = new SqlConnection())
        {
            conn.ConnectionString = dsn;
            using (SqlCommand command = conn.CreateCommand())
            {
                command.CommandType = commandType;
                connection.Open();
                specificPreparations(command);
                SqlDataReader reader = command.ExecuteReader();
                results.Load(reader);
            }
        }

        return results;
    }
}
那么就称之为:

ds = SqlHelper.ExecuteDataset(GlobalSettings.DbDSN, 
    CommandType.Text,
    delegate(SqlCommand command)
    {
        command.CommandText = "SELECT BLAH FROM BLAH";

        foreach (var myParameter in myParameterList)
        {
            SqlParameter p = new SqlParameter();
            // Construct p
            command.Paramters.Add(p)
        }
        // Anything else you want to do to the command
    });
}
将SqlHelper.ExecutedataSets更改为需要委托调用所需的特定代码:

class SqlHelper
{
    public delegate void SqlCommandDelegate(SqlCommand command);

    public Dataset ExecuteDataset(string dsn, 
            CommandType commandType, 
            SqlCommandDelegate specificPreparations)
    {
        Dataset results;
        using (SqlConnection conn = new SqlConnection())
        {
            conn.ConnectionString = dsn;
            using (SqlCommand command = conn.CreateCommand())
            {
                command.CommandType = commandType;
                connection.Open();
                specificPreparations(command);
                SqlDataReader reader = command.ExecuteReader();
                results.Load(reader);
            }
        }

        return results;
    }
}
那么就称之为:

ds = SqlHelper.ExecuteDataset(GlobalSettings.DbDSN, 
    CommandType.Text,
    delegate(SqlCommand command)
    {
        command.CommandText = "SELECT BLAH FROM BLAH";

        foreach (var myParameter in myParameterList)
        {
            SqlParameter p = new SqlParameter();
            // Construct p
            command.Paramters.Add(p)
        }
        // Anything else you want to do to the command
    });
}

您可以使用SP执行此操作

    CREATE  PROCEDURE MyDynamicSP(@Condition1 as varchar(100),Condition2 as varchar(100),Condition3 as varchar(100))
    AS
    SET NOCOUNT ON

    DECLARE @STRSQL VARCHAR(1000)

    SET @STRSQL = 'SELECT * FROM MyTable WHERE '
    IF NOT @Condition1 IS NULL
        @STRSQL = @STRSQL + ' ' + @Condition1

    IF NOT @Condition2 IS NULL
        @STRSQL = @STRSQL + ' ' + @Condition2

    IF NOT @Condition3 IS NULL
        @STRSQL = @STRSQL + ' ' + @Condition3

    EXEC sp_executesql @STRSQL

    SET NOCOUNT OFF

您可以使用SP执行此操作

    CREATE  PROCEDURE MyDynamicSP(@Condition1 as varchar(100),Condition2 as varchar(100),Condition3 as varchar(100))
    AS
    SET NOCOUNT ON

    DECLARE @STRSQL VARCHAR(1000)

    SET @STRSQL = 'SELECT * FROM MyTable WHERE '
    IF NOT @Condition1 IS NULL
        @STRSQL = @STRSQL + ' ' + @Condition1

    IF NOT @Condition2 IS NULL
        @STRSQL = @STRSQL + ' ' + @Condition2

    IF NOT @Condition3 IS NULL
        @STRSQL = @STRSQL + ' ' + @Condition3

    EXEC sp_executesql @STRSQL

    SET NOCOUNT OFF

您可以在查询内部执行以下测试:

SELECT *whatever you need*
    FROM [tbl_Projects] 
    where 
        (@Category is null or [Category] = @Category)  and
        (@Country is null or [Country] = @country) and 
        (@val1 is null or value > @val1) and 
        (@val2 is null or value < @val2)    
    order by CreatedDate asc
您总是发送4个参数。另一方面,您可以在SQL工作表中构建查询,这样更容易发现语法错误等等


不过,您可能需要为空值添加一些测试。

您可以在查询中这样做:

SELECT *whatever you need*
    FROM [tbl_Projects] 
    where 
        (@Category is null or [Category] = @Category)  and
        (@Country is null or [Country] = @country) and 
        (@val1 is null or value > @val1) and 
        (@val2 is null or value < @val2)    
    order by CreatedDate asc
您总是发送4个参数。另一方面,您可以在SQL工作表中构建查询,这样更容易发现语法错误等等


不过,您可能需要为空值添加一些测试。

这在我看来像是C。你能给你的问题贴上相应的标签吗?@FabianBigler是的,我在我的sql查询中添加了一些C代码来处理这个问题。这太愚蠢了。现在我正试图通过sql本身来解决这个问题。这就是这篇文章的原因。我也按照你说的那样编辑了标签。如果这个解决方案只有C,我不想错过itOK。我希望我的回答能帮助你。其实很简单,我觉得这像C。你能给你的问题贴上相应的标签吗?@FabianBigler是的,我在我的sql查询中添加了一些C代码来处理这个问题。这太愚蠢了。现在我正试图通过sql本身来解决这个问题。这就是这篇文章的原因。我也按照你说的那样编辑了标签。如果这个解决方案只有C,我不想错过itOK。我希望我的回答能帮助你。它实际上非常简单。您可以简单地重载ExecuteDataset,以便在不需要时省略parametersparameter。我不确定,但是,这段代码在我的c文件中不起作用。主要是这一行var参数作为新的ListofSqlParameter;我需要添加任何名称空间xtra吗?需要。StringBuilder的命名空间System.Text。和System.Collections.Generic对于ListOf SqlParameter,您可以简单地重载ExecuteDataset,以便在不需要时可以忽略parameters参数。我不确定,但是,此代码在我的c文件中不起作用。主要是这一行var参数作为新的ListOf SqlParameter;我需要添加任何名称空间xtra吗?需要。StringBuilder的命名空间System.Text。和System.Collections.Generic,用于SqlParameter的列表