0

我有一种情况,我的 sql 查询的参数是动态的。如果参数为空,我不想将它添加到查询中,我已经尝试了一些事情(从未工作过)..现在对我来说看起来很愚蠢

  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));

我也在 这里检查了 Building dynamic sql 但是在我需要在关键词之间放置like 和之间没有用..有人可以帮我解决这个问题吗?

4

4 回答 4

1

您可以使用 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
于 2013-07-26T11:41:50.960 回答
1

进行更改SqlHelper.ExecuteDataset,以便委托调用您想要的特定代码:

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
    });
}
于 2013-07-26T11:39:49.063 回答
1

只是给你一个想法,我会做这样的事情:

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-Class,您可能需要除 List(Of SqlParameter) 之外的其他东西。

于 2013-07-26T11:29:12.903 回答
1

您可以像这样在查询中进行测试:

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 工作表中构建查询,并且更容易发现语法错误等等。

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

于 2013-07-26T11:45:12.723 回答