sql >> Database teknologi >  >> RDS >> Oracle

Hvordan kan du tvinge en funktion i en where-klausul til at udføre én gang i oracle?

Hvorfor bruger du overhovedet PL/SQL til dette? Ud fra det du har sagt, laver du noget matematik, hvorfor ikke bare gøre det i SQL? Dette vil også være muligt med en kombination af INSTR og SUBSTR, men det er smukkere at se på med REGEXP_SUBSTR.

select to_number(regexp_substr(ip, '[^.]+', 1, 1)) * power(2,24)
        + to_number(regexp_substr(ip, '[^.]+', 1, 2)) * power(2,16)
        + to_number(regexp_substr(ip, '[^.]+', 1, 3)) * power(2,8)
        + to_number(regexp_substr(ip, '[^.]+', 1, 4))
     , icb.*
     , icl.* 
  from ip_city_block icb
  join ip_city_location icl
    on icl.locid = icb.locid  
 where to_number(regexp_substr(ip, '[^.]+', 1, 1)) * power(2,24)
        + to_number(regexp_substr(ip, '[^.]+', 1, 2)) * power(2,16)
        + to_number(regexp_substr(ip, '[^.]+', 1, 3)) * power(2,8)
        + to_number(regexp_substr(ip, '[^.]+', 1, 4))
       between icb.startipnum and icb.endipnum

SQL Fiddle demonstration af REGEXP_SUBSTR output

Hvis du har for at gøre dette i PL/SQL skal du gøre to ting:

  1. Se, om du kan erklære din funktion som deterministisk .
  2. Prøv og drag fordel af sub -forespørgselscache .

Det ser ud som om du allerede laver 2, men du kan prøve at udvide dette ved at bruge en WITH-sætning:

with the_ip as ( select get_ip_integer('74.253.103.98') as ip from dual )
select the_ip.ip
     , icb.*
     , icl.* 
  from ip_city_block icb
  join ip_city_location icl
    on icl.locid = icb.locid
  join the_ip
    on the_ip.ip between icb.startipnum and icb.endipnum


  1. Forespørgsel for at finde fuld tabelscanninger i Oracle

  2. Implementering af SQL Server Performance Indicator for forespørgsler, lagrede procedurer og triggere

  3. Sammenføjning af 2 store postgres-borde ved hjælp af int8range skaleres ikke godt

  4. php MySql forbindelsesfejl