C# 使用关键字between和order构建动态sql查询
我遇到的情况是,sql查询的参数是动态的。如果参数为null,我不想将其添加到查询中,我尝试了一些从未奏效的方法。现在我觉得它像个傻瓜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
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的列表