简体   繁体   English

Oracle SQL使用Coalesce

[英]Oracle SQL use Coalesce

I have this query that works in Oracle but I want to convert it to use Coalesce because of some problems I'm having with Visual Studio. 我有此查询可在Oracle中使用,但由于与Visual Studio有关的某些问题,我希望将其转换为使用Coalesce。

SELECT * 
FROM a Left Join b on b.institution_code=a.institution_code
WHERE 
      (upper(a.Login_Name)=UPPER('%' || :Login_Name || '%') OR :Login_Name IS NULL)
  AND (upper(a.Display_Name) Like  UPPER('%' || :Display_Name || '%')   OR :Display_Name IS NULL) 
  AND (upper(a.Email_Address)=UPPER(:Email_Address) OR :Email_Address IS NULL) 
  AND ((a.institution_code=:institution_code) OR :institution_code IS NULL)  
  AND (upper(b.institution_desc) Like  UPPER('%' || :institution_desc || '%')   OR :institution_desc IS NULL)

This works 这有效

WHERE
Upper(a.Display_Name) LIKE Upper('%' || COALESCE(:Display_Name,a.Display_Name) || '%')
AND upper(a.Login_Name)=Upper(COALESCE(:Login_Name,a.Login_Name))    
AND upper(a.Email_Address)=Upper(COALESCE(:Email_Address,a.Email_Address))

but when I try to convert the institution_code and institution_desc field to use coalesce i don't get any results from the queries. 但是,当我尝试转换stitutional_code和institutional_desc字段以使用合并时,我没有从查询中得到任何结果。

when i add these lines there are no results 当我添加这些行时没有结果

    AND a.institution_code=COALESCE(:institution_code,a.institution_code)
  AND (Upper(b.institution_desc) LIKE Upper('%' || COALESCE(:institution_desc,b.institution_desc) || '%'))
AND ((a.institution_code=:institution_code) OR :institution_code IS NULL)

is not equivalent to 不等于

AND a.institution_code=COALESCE(:institution_code,a.institution_code)

IF a.institution_code IS NULL and :institution_code IS NULL, then the first example will be true (because the second part of the OR is true), but the second will not (because NULL=NULL is not true). 如果a.institution_code为NULL和:institution_code为NULL,则第一个示例为true(因为OR的第二部分为true),但第二个示例为true(因为NULL = NULL不为真)。

WHERE (UPPER(a.Login_Name) = UPPER('%' || :Login_Name || '%') OR :Login_Name IS NULL)

...should be: ...应该:

WHERE (:Login_Name IS NULL OR UPPER(a.Login_Name) = UPPER('%' || :Login_Name || '%'))

You want to check the bind variable FIRST - otherwise you're doing data comparison before knowing that you want everything anyways. 您要检查绑定变量FIRST-否则,在知道仍然需要所有内容之前,先进行数据比较。 You're getting the worst possible performance out of the query. 您正在从查询中获得最差的性能。

Next, if you're going to run UPPER on numerous columns - use Subquery Factoring to have it performed first: 接下来,如果要在许多列上运行UPPER,请使用Subquery Factoring使其首先执行:

WITH upper_a AS (
SELECT a.pk,
       UPPER(a.login_name) 'login_name',
       UPPER(a.display_name) 'display_name',
       UPPER(a.email_address) 'email_address',
       UPPER(b.institution_desc) 'institution_desc'
  FROM a)
SELECT *
  FROM A a
  JOIN upper_a ua ON ua.pk = a.pk
 WHERE :Login_Name IS NULL OR ua.login_name = v_login_name

Oracle doesn't do WHERE (parmeter IS NULL OR t.col = parameter) well, and you get nothing by using bind variables for parameters with optional values. Oracle不能很好地处理WHERE(参数IS为NULL或t.col =参数)的情况,并且通过对具有可选值的参数使用绑定变量,您将一无所获。 What you really want to use is CONTEXT variables (available since 9i). 您真正想要使用的是CONTEXT变量(自9i起可用)。

I suspect the problem is the 2nd line ( b.institution_desc ). 我怀疑问题出在第二行( b.institution_desc )。 Specifically, you have the possibility for a NULL LIKE NULL situation, and NULL LIKE NULL returns false. 特别是,您可能会出现NULL LIKE NULL情况,并且NULL LIKE NULL返回false。

Try it like this: 像这样尝试:

AND Upper(b.institution_desc) LIKE '%' || Upper(COALESCE(:institution_desc,b.institution_desc,'')) || '%'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM