Oracle
 sql >> база данни >  >> RDS >> Oracle

Условие WHERE за нулев входен параметър на Oracle PL\SQL

Един от методите би бил да използвате вариант на

 WHERE column = nvl(var, column)

Тук обаче има два капана:

  1. ако колоната е nullable, тази клауза ще филтрира null стойности, докато във вашия въпрос не бихте филтрирали null стойностите във втория случай. Можете да модифицирате тази клауза, за да вземе предвид нули, но става грозно:

        WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
    

    Разбира се, ако по някакъв начин impossible_value бъде вмъкнат, ще се натъкнете на друг вид (забавни) проблеми.

  2. Оптимизаторът не разбира правилно този тип клауза. Понякога ще създаде план с UNION ALL, но ако има повече от няколко nvl , ще получите пълно сканиране, дори ако са налице напълно валидни индекси.

Ето защо, когато има много параметри (няколко полета за търсене в голяма форма например), обичам да използвам динамичен SQL:

DECLARE
   l_query VARCHAR2(32767) := 'SELECT ... JOIN ... WHERE 1 = 1';
BEGIN
   IF param1 IS NOT NULL THEN
      l_query := l_query || ' AND column1 = :p1';
   ELSE 
      l_query := l_query || ' AND :p1 IS NULL';
   END IF;
   /* repeat for each parameter */
   ...
   /* open the cursor dynamically */
   OPEN your_ref_cursor FOR l_query USING param1 /*,param2...*/; 
END;

Можете също да използвате EXECUTE IMMEDIATE l_query INTO l_result USING param1;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да добавите първичен ключ към изглед на Oracle?

  2. Как да копирам или импортирам схеми на Oracle между две различни бази данни на различни сървъри?

  3. PL/SQL - Използване на променлива на списък в клауза Where In

  4. как да изберете само ред с максимална последователност, без да използвате подзаявка?

  5. Oracle:как да добавя минути към времева марка?