OraQA

Oracle Question and Answer

  • Do you have a solution to a problem? Do you have an unanswered question? Login and share it with the Oracle community. More...

Oracle News


Entries RSS feed

Comments RSS feed

Is it best to use SQL or PL/SQL?

November 9th, 2008 By Laurent Schneider

The issue is very often related to context switching. A context switch is when you write plsql code that contains sql statement, or sql that contains plsql functions.

select emp,dbms_random.value from emp;

implies a context switch

begin update emp set sal=0; end;

implies a context switch too.

However, it is sometimes better practice to have a few context switches rather than a way too much complex SQL query, that nobody will ever be able to maintain but you.

Ok, let’s try to print the equation abc+def=ghi where abcdefghi are digits from 1 to 9 with no duplicate.

SQL> create or replace function f return sys.odcivarchar2list pipelined deterministic is
  2    a7 number;
  3    a8 number;
  4    a9 number;
  5  begin
  6    -- How to solve the 3 Digits Plus 3 Digits Puzzle
  7    -- where a1a2a3 + a4a5a6 = a7a8a9 and each a is an unique digit from 1 to 9
  8    for a1 in 1..9 loop
  9      for a2 in 1..9 loop
 10        if a2 not in (a1) then
 11          for a3 in 1..9 loop
 12            if a3 not in (a1,a2)
 13            then
 14              for a4 in 1..9 loop
 15                if a4 not in (a1,a2,a3) and a1+a4<10
 16                then
 17                  for a5 in 1..9 loop
 18                    if a5 not in (a1,a2,a3,a4) and a1*10+a2+a4*10+a5<100
 19                    then
 20                      for a6 in 1..9 loop
 21                        if a6 not in (a1,a2,a3,a4,a5) and a1*100+a2*10+a3+a4*100+a5*10+a6<1000
 22                        then
 23                          a9:=a3+a6;
 24                          a8:=trunc(a9/10);
 25                          a9:=a9-a8*10;
 26                          if a9 not in (a1,a2,a3,a4,a5,a6,0)
 27                          then
 28                            a8:=a8+a2+a5;
 29                            a7:=trunc(a8/10);
 30                            a8:=a8-a7*10;
 31                            if a8 not in (a1,a2,a3,a4,a5,a6,a9,0)
 32                            then
 33                              a7:=a7+a1+a4;
 34                              if a7 not in (a1,a2,a3,a4,a5,a6,a8,a9,0)
 35                              then
 36                                pipe row(a1||a2||a3||'+'||a4||a5||a6||'='||a7||a8||a9);
 37                              end if;
 38                            end if;
 39                          end if;
 40                        end if;
 41                      end loop;
 42                    end if;
 43                  end loop;
 44                end if;
 45              end loop;
 46            end if;
 47          end loop;
 48        end if;
 49      end loop;
 50    end loop;
 51  end;
 52  /

Function created.

SQL>
SQL> set timi on
SQL> select column_value as Equation_str, decode(rownum,1,count(*) over()) cnt from table(f);
124+659=783                 336
125+739=864
...
784+152=936

336 rows selected.

Elapsed: 00:00:00.96
SQL>
SQL> SELECT num1||' + '||num2||' = '|| num3 as Equation_str,
  2         CASE WHEN lag(cnt) over (order by num1)  cnt
  3                OR lag(cnt) over (order by num1) IS NULL
  4       THEN  cnt END AS Counter
  5  FROM
  6  (SELECT num1, num2, num3, count(*) over ( ) as cnt
  7   FROM
  8   (SELECT substr(num,1,3) num1, substr(num,4,3) num2, substr(num,7,3) num3
  9    FROM
 10    (SELECT replace(sys_connect_by_path(n,','), ',') num
 11     FROM (SELECT LEVEL n FROM dual CONNECT BY LEVEL <=9)
 12     WHERE LEVEL = 9
 13     CONNECT BY NOCYCLE PRIOR n != n
 14     AND LEVEL <=9
 15     AND CASE LEVEL
 16              WHEN 1
 17              THEN CASE WHEN n < 9 THEN 1 END
 18              WHEN 4
 19              THEN CASE WHEN n  + CONNECT_BY_ROOT(n) = 3 THEN 1 END
 23                        ELSE CASE WHEN n >= CONNECT_BY_ROOT(n) + 1 THEN 1 END
 24                   END
 25             ELSE 1 END = 1
 26     )
 27    )
 28   WHERE to_number(num1)     + to_number(num2)       =  to_number(num3)
 29   );
124 + 659 = 783             336
125 + 739 = 864
...
784 + 152 = 936

336 rows selected.

Elapsed: 00:00:22.91

hmm, do not you just love select * from table(f); ? Just a sinister scheme to seduce you.

Leave a Reply

You must be logged in to post a comment.

RSS feed for comments on this question