My experience with SQL is essentially with the following databases:
SQL language is a bit underrated. If you combine it with some scripting features like with PL/SQL, you can get functional applications. Of course, not like under Windows, the interface is just text commands. I had a look at Oracle PL/SQL, which reminds me of Pascal in many aspects, for example declaring the variables before the block of instructions and nested procedures.
Here is for example a code of PL/SQL to compute prime numbers using a table. This is clearly not the most efficient way, as using RAM is of course faster than accessing the disk.
It is composed of two packages. primes_actions provides access to a table containing numbers to be checked, and primes_compute contains the code the do the sieve of Eratosthene.
create table primes (idint not null , isprimechar (1)check (isprimein ('Y','N'))not null ,primary key (id));
create or replace package primes_actionsis subtype t_numberis primes.id%type ;subtype t_isprimeis primes.isprime%type ;type t_number_tableis table of t_number;function isprime_to_bool(p_isprime t_isprime)return boolean ;function bool_to_isprime(p_boolboolean )return t_isprime;procedure init_table (p_max_value t_number, p_isprime_boolboolean );function can_be_prime (p_prime t_number)return boolean ;function collect_primesreturn t_number_table;procedure update_range (p_primes t_number_table, p_areprime_boolboolean );end primes_actions;
create or replace package body primes_actionsis function bool_to_isprime(p_boolin boolean )return t_isprimeis begin if p_boolthen return 'Y';else return 'N';end if ;end bool_to_isprime;function isprime_to_bool(p_isprimein t_isprime)return boolean is begin if p_isprime = 'Y'then return true ;else return false ;end if ;end isprime_to_bool;procedure init_table (p_max_valuein t_number, p_isprime_boolin boolean )is v_all t_number_table; v_already t_number; v_start t_number; v_isprime t_isprime;begin --convert parameter v_isprime := bool_to_isprime(p_isprime_bool);--slice the existing table delete from primeswhere id > p_max_value;update primesset isprime = v_isprime;--expand the existing table if needed select max (id)into v_alreadyfrom primes;if v_alreadyis null then v_start := 2;else v_start := v_already+1;end if ;if v_start <= p_max_valuethen v_all := t_number_table();for iin v_start .. p_max_valueloop v_all.extend(); v_all(v_all.last ) := i;end loop ;forall iin v_all.first .. v_all.last insert into primes (id,isprime)values (v_all(i),v_isprime);end if ;end init_table;function collect_primesreturn t_number_tableis v_primes t_number_table; v_isprime t_isprime;begin v_isprime := bool_to_isprime(true );select idbulk collect into v_primesfrom primeswhere isprime = v_isprimeorder by id;return v_primes;end collect_primes;procedure update_range (p_primesin t_number_table, p_areprime_boolin boolean )is v_isprime t_isprime;begin v_isprime := bool_to_isprime(p_areprime_bool);forall nin p_primes.first .. p_primes.last update primesset isprime = v_isprimewhere id = p_primes(n);end update_range;function can_be_prime (p_prime t_number)return boolean is v_isprime t_isprime;begin select isprimeinto v_isprimefrom primeswhere id = p_prime;return isprime_to_bool(v_isprime);end can_be_prime;end primes_actions;
create or replace package primes_computeis procedure show_primes (p_maxvaluein primes_actions.t_number);procedure private_sieve_init (p_max_valuein primes_actions.t_number);procedure private_sieve_run (p_max_valuein primes_actions.t_number);end ;
create or replace package body primes_computeis procedure private_sieve_init (p_max_valuein primes_actions.t_number)is begin --presuppose all numbers are prime primes_actions.init_table (p_max_value,true );end ;procedure private_sieve_run (p_max_valuein primes_actions.t_number)is i primes_actions.t_number;procedure remove_multiple (p_basevaluein primes_actions.t_number)is v_multiple primes_actions.t_number; v_exclude primes_actions.t_number_table;begin if p_basevalue < 1then return ;end if ; v_exclude := primes_actions.t_number_table(); v_multiple := p_basevalue;loop v_multiple := v_multiple + p_basevalue;exit when v_multiple > p_max_value; v_exclude.extend; v_exclude(v_exclude.last ) := v_multiple;end loop ; primes_actions.update_range(v_exclude,false );end ;begin for iin 2 .. p_max_valueloop if primes_actions.can_be_prime(i)then remove_multiple(i);end if ;end loop ;end ;procedure show_primes (p_maxvaluein primes_actions.t_number)is v_timer_starttimetimestamp ; v_accvarchar2 (2000); v_primes primes_actions.t_number_table; v_curprime primes_actions.t_number;procedure timer_startis begin v_timer_starttime := SYSTIMESTAMP;end ;function timer_elapsedreturn varcharis begin return (extract (second from (SYSTIMESTAMP - v_timer_starttime)) * 1000) || ' ms';end ;procedure timer_log(p_text varchar)is begin dbms_output.put_line(timer_elapsed() || ': ' || p_text);end ;procedure output_startis begin v_acc := '';end ;procedure output_next(p_element varchar)is v_new_length int;begin v_new_length :=length (v_acc) +length (p_element) + 1;if (v_new_length > 80)and (length (v_acc) > 0)then dbms_output.put_line(v_acc); v_acc := p_element || ', ';elsif (v_new_length = 80)then v_acc := v_acc || p_element || ','; dbms_output.put_line(v_acc); v_acc := '';else v_acc := v_acc || p_element || ', ';end if ;end ;procedure output_endis begin if length (v_acc) > 0then dbms_output.put_line(v_acc || ' ...');end if ;end ;begin timer_start(); timer_log('Initialising sieve...'); private_sieve_init(p_maxvalue); timer_log('Computing sieve...'); private_sieve_run(p_maxvalue); timer_log('Done.'); output_start(); v_primes := primes_actions.collect_primes(); v_curprime := v_primes.first ;while v_curprimeis not null loop output_next(v_primes(v_curprime)); v_curprime := v_primes.next(v_curprime);end loop ; output_end();end ;end ;
begin primes_compute.show_primes(500);end ;
0 ms: Initialising sieve... 30 ms: Computing sieve... 165 ms: Done. 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, ... Statement processed.
![]() |
![]() |
![]() |