簡體   English   中英

mysql select查詢中的可選參數

[英]Optional Parameters in mysql select query

我正在嘗試在我的項目中實現可選搜索,該項目具有五個可選輸入值(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',則必須將其忽略(或),依此類推...

一些建議:

  1. 首先直接運行查詢(例如,在某些查詢編輯器UI中)(您可能已經在執行此操作,但是如果沒有,這將有所幫助)
  2. 使用ANSI樣式FROM語法將三個表( FROM子句)的FROM條件與WHERE子句中的過濾條件明確分開
  3. 您的第一個示例(其中測試參數為NULL並具有OR條件)可能會更簡單,因為引擎可以立即確定WHERE子句的該部分為TRUE,而不是使用模擬的LIKE實際測試行值。運算符使用“ %%”
  4. 首先使用聯接的表運行查詢(在編輯器中),但注釋掉整個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”等。

接下來,由於您始終以字母開頭,並且CONDITIONALLY開頭為company和package,因此我默認將ID列上的company和package表分別默認為JOIN,這將是它們的自然聯接。

現在,按照您的標准。 要僅基於您實際為其提供數據的結果,那是什么條件。 如果您不輸入公司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] something%”,並且可能找不到預期的值。 但是查詢的上下文應該起作用,除非字母表中的條目並不總是與給定的公司和/或包裝相關聯,這將使其失敗,而不是使用LEFT-JOIN。

另外,如果您提供的值是公司或包裝的SINGLE 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM