sql >> Databáze >  >> RDS >> Oracle

Jak můžete přinutit funkci v klauzuli where, aby se jednou provedla v orákulu?

Proč k tomu vůbec používáte PL/SQL? Z toho, co jste řekl, že děláte nějakou matematiku, proč to neudělat jen v SQL? To bude také možné s kombinací INSTR a SUBSTR, ale na pohled je to hezčí s 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

Ukázka SQL Fiddle výstupu REGEXP_SUBSTR

Pokud máte Chcete-li to provést v PL/SQL, měli byste udělat dvě věci:

  1. Podívejte se, zda můžete svou funkci deklarovat jako deterministický .
  2. Vyzkoušejte a využijte výhod sub -ukládání dotazů do mezipaměti .

Zdá se, že už děláte 2, ale můžete to zkusit rozšířit pomocí klauzule WITH:

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. Databáze správce balíčků GI 19c RPM

  2. Pomozte upravit JSON, abyste vytvořili pole spíše než „slovník“

  3. rake db:create throws databáze neexistuje chyba s postgresql

  4. ORA-06531 po upgradu Oracle