C# mysql选择查询中的可选参数
我试图在我的项目中实现可选搜索,它有五个输入值作为可选值(CompanyID、PackageID、SubjectID、Fromdate和Todate) 我将mysql查询编写为C# mysql选择查询中的可选参数,c#,mysql,select,optional-parameters,C#,Mysql,Select,Optional Parameters,我试图在我的项目中实现可选搜索,它有五个输入值作为可选值(CompanyID、PackageID、SubjectID、Fromdate和Todate) 我将mysql查询编写为 select l.RefNo, l.LetterDate, l.CompanyID, l.Subject, c.CompanyID, c.CompanyCode, p.PackageName, p.PackageID from tblletter l, tblcompany c, t
select l.RefNo, l.LetterDate, l.CompanyID, l.Subject,
c.CompanyID,
c.CompanyCode,
p.PackageName, p.PackageID
from tblletter l,
tblcompany c,
tblpackage p
where
(companyID is null or l.CompanyID = companyID ) and
(packageID is null or l.PackageID = packageID) and
(subjectID is null or l.LetterID = subjectID);
但是我不能得到结果,我需要一个语法来将日期值发送为null,我已经尝试了
DateTime?fromdate=..
这个语法正确吗?
多谢各位
将我的代码更新为
select l.RefNo, l.LetterDate, l.CompanyID, l.Subject,
Case LetterType
When 1 then 'PSK'
When 2 then c.CompanyCode
End As FromCompany,
Case LetterType
When 1 then c.CompanyCode
When 2 then 'PSK'
End As ToCompany,
c.CompanyCode,
p.PackageID
from tblletter l,
tblcompany c ,
tblpackage p
where l.CompanyID = c.CompanyID and l.PackageID = p.PackageID and
l.CompanyID Like
case
when l.CompanyID = c.CompanyID and companyID > 0 then ('%' + LTRIM(companyID) + '%')
else '%%'
end
and l.PackageID Like
case
when l.PackageID = p.PackageID and packageID > 0 then ('%' + LTRIM(packageID) + '%')
else '%%'
end
and l.Subject =
case
when subjectName is not null then subjectName
else '%%'
end;
但是仍然得到空表值
the possible cases are
1). companyID = 30 or packageID = 0 or subjectName = null
2). companyID = 0 or packageID = 11 or subjectName = null
3). companyID = 0 or packageID = 0 or subjectName = 'sand'
4). companyID = 30 and packageID = 11 or subjectName = null
5). companyID = 30 or packageID = 0 and subjectName = 'sand'
此处,如果值为“0”,则必须忽略(或)
等等。。。比如…一些建议:
)中的筛选条件
其中
子句
WHERE
子句的那一部分为TRUE,而不是使用“%”来实际测试行值WHERE
子句,确保看到数据。
然后,开始逐段取消注释WHERE
子句,
包括参数值(或它们所在的文字),确保
您可以在每个步骤中看到预期的结果。这将有助于缩小范围
停止您的故障排除过程SELECT
l.RefNo, l.LetterDate, l.CompanyID, l.Subject,
Case LetterType
When 1 then 'PSK'
When 2 then c.CompanyCode
End As FromCompany,
Case LetterType
When 1 then c.CompanyCode
When 2 then 'PSK'
End As ToCompany,
c.CompanyCode,
p.PackageID
FROM tblletter l
INNER JOIN tblcompany c ON l.CompanyID = c.CompanyID --make sure whether this should be INNER or LEFT OUTER join
INNER JOIN tblpackage p ON l.PackageID = p.PackageID --make sure whether this should be INNER or LEFT OUTER join
WHERE 1 = 1 --useful if commenting and uncommenting additional parts of WHERE clause
AND (companyID is null OR l.CompanyID = companyID) -- can do the LIKE version instead, but may be slower... test both
AND (packageID is null OR p.PackageID = packageID) -- can do the LIKE version instead, but may be slower... test both
AND (subjectName is null OR l.Subject = subjectName) -- can do the LIKE version instead, but may be slower... test both
;
首先,您的参数与列的名称相同,这肯定会造成一些混乱。我会用某种前缀来重命名它们,比如“parmCompanyID”、“parmPackageID”等等 接下来,由于您总是以字母开头,并且有条件地连接到公司和包,因此我默认在ID列上分别连接到公司和包表,这将是它们的自然连接 现在,谈谈你的标准。要仅基于您实际提供的数据获得结果,条件是什么。如果你不输入一个公司ID,你就不在乎并得到所有的ID 如果你确实为公司投入了价值,你只想要那些符合条件的。因此,连接总是基于ID,但是您的where可以添加额外的条件。如果您提供的是一个ID字符串,那么如果字符串的长度为0(无),则始终返回TRUE,是包括公司。如果长度>0(已提供),则仅当该ID在列表中时才返回true 类似的应用程序适用于您的其他标准。差不多
select
l.RefNo,
l.LetterDate,
l.CompanyID,
l.Subject,
Case LetterType
When 1 then 'PSK'
When 2 then c.CompanyCode End As FromCompany,
Case LetterType
When 1 then c.CompanyCode
When 2 then 'PSK' End As ToCompany,
c.CompanyCode,
p.PackageID
from
tblletter l,
JOIN tblcompany c
ON l.CompanyID = c.CompanyID
JOIN tblpackage p
ON l.PackageID = p.PackageID
where
CASE WHEN LENGTH( LTRIM( parmCompanyID )) = 0
THEN 1
ELSE l.CompanyID LIKE '%' + LTRIM(parmCompanyID) + '%' end
AND
CASE WHEN LENGTH( LTRIM( parmPackageID )) = 0
THEN 1
ELSE l.PackageID LIKE '%' + LTRIM(parmPackageID) + '%' end
AND
CASE WHEN LENGTH( LTRIM( parmSubject )) = 0
THEN 1
ELSE l.Subject LIKE '%' + LTRIM(parmSubject) + '%' end
反馈
可能是因为LTRIM()而不是完全修剪()。如果您的参数有前导空格,则通配符匹配将类似于“%[space][space]something%”,并且可能无法按预期找到。但是,除非字母表中的条目并不总是与给定的公司和/或包相关联,否则查询的上下文应该是有效的,这会导致查询失败,而不是使用左连接
此外,如果您提供的值是公司或软件包的单个ID,那么您无论如何都不应该使用。。。您可能需要更改为
where
CASE WHEN parmCompanyID = 0
THEN 1
ELSE l.CompanyID = parmCompanyID end
AND
CASE WHEN parmPackageID = 0
THEN 1
ELSE l.PackageID = parmPackageID end
AND
CASE WHEN LENGTH( LTRIM( parmSubject )) = 0
THEN 1
ELSE l.Subject LIKE '%' + LTRIM(parmSubject) + '%' end
不要在查询中添加可选参数,而是尝试使用代码中的条件创建查询,以便最终查询只包含所需的参数\n因此,是否需要编写五个单独的存储过程,每个存储过程包含一个参数@manojNo不,对不起,我不知道这是一个存储过程,我想你是直接从你的c#程序启动一个查询。谢谢你的回复@DRapp。。。但是“%”在mysql中不起作用。。我测试了这个查询,但仍然得到空结果。@htiru,抱歉延迟响应。请参阅修改后的答案。很抱歉,我仍然不使用单个输入值,而使用所有输入值`其中CASE WHEN 35=0,则1 ELSE l.CompanyID=35 end,CASE WHEN 11=0,则1 ELSE l.PackageID=11 end,CASE WHEN LENGTH(LTRIM(4))=0,然后1,其他l。主题如LTRIM('sand')end`@htiru,您能否编辑您现有的问题,转到问题的结尾,并使用您试图模拟处理的值的一些实际样本进行编辑。。。单个、多个、字符串值?什么。。。谢谢你的回复。。。这是代码(35为null或l.CompanyID=35)--可以执行类似的版本,但速度可能较慢。。。同时测试和(0为null或p.PackageID=0)--可以执行类似的版本,但速度可能较慢。。。同时测试和(null为null或l.Subject=null)它类似于仅包含companyID的值。。但是仍然得到空结果。@htiru-就像我在上面的#4中所说的那样,首先尝试在不使用
WHERE
子句的情况下运行查询,以便验证表联接是否按预期方式工作。如果没有取回数据,则FROM
子句中存在问题。如果您确实获得了数据,您可以开始逐个添加过滤器(您的WHERE
子句),并在每个步骤中进行测试,以查看是什么导致数据被过滤掉。如果没有WHERE子句,效果很好,连接也做得很好@SlimsGhost@htiru-所以连接工作正常,很好。现在,如果您将WHERE子句的各个部分添加回(一个接一个),您应该能够看到为什么要返回的数据会被过滤掉。这应该只是一个消除的过程,然后找出问题过滤器没有按照您的要求进行操作的原因。