mysql select query中的可选参数

时间:2016-02-15 08:47:02

标签: 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,
   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'它必须被忽略(或) 等等... ... ...

2 个答案:

答案 0 :(得分:0)

一些建议:

  1. 首先直接运行您的查询(例如在某些查询编辑器UI中)(您 可能已经这样做了,但如果没有,它会有所帮助)
  2. 使用ANSI 样式连接语法可以清楚地分隔三者的连接标准 表格(FROM子句)来自您的过滤器条件 WHERE条款
  3. 您的第一个示例,您在其中测试参数 对于NULL并且具有OR条件,可能更简单,因为引擎 可以立即确定WHERE子句的一部分为TRUE,而不是使用'%%'
  4. 使用dummied up LIKE运算符实际测试行值
  5. 首先使用已连接的表运行查询(在编辑器中) 注释掉整个WHERE子句并确保您看到数据。 然后,开始逐个取消注释WHERE子句, 包括参数值(或其文字),确保 您会看到每个步骤所期望的结果。这将有助于缩小范围 排除故障排除过程。
  6. 以下是展示这些想法的示例查询:

    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
    ;
    

答案 1 :(得分:0)

首先,你的参数与列名相同,肯定会引起一些混乱。我会用某种前缀重命名,只是为了区分它们,例如“parmCompanyID”,“parmPackageID”等。

接下来,由于您总是以字母开头,并且对公司和软件包来说是条件性的,因此我已经默认分别在ID列上加入公司和包表,这将是他们的自然联接。

现在,按照您的标准。要仅根据您实际提供数据的结果获得结果,该条件是什么。如果你没有加入公司ID,你就不在乎并得到所有这些。

如果您为公司投入了一个价值,那么您只需要那些符合条件的人。因此,JOIN始终基于ID,但您可以在哪里添加EXTRA标准。如果您提供一串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()而不是FULL TRIM()。如果您的参数具有前导空格,则您的外卡匹配将类似于'%[space] [space] some%'并且可能无法按预期找到。但是查询的上下文应该有效,除非字母表中的条目并不总是与给定的公司和/或包相关联,这会使它失败而不是使用LEFT-JOIN。

此外,如果您提供的价值是公司或包裹的单一ID,那么您不应该使用LIKE ......您可能需要更改为...

   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