私は同じパフォーマンスの間違いを犯すのをやめたいと思っており、SQL ステートメントに関しては、私よりもずっと安定した人が必要です。
基本的に私は私の機能が欲しい:
create or replace FUNCTION SEQGEN(vinp in varchar2, iSeq in INTEGER)
RETURN VARCHAR2 is vResult VARCHAR2(32);
iBas INTEGER; iRem INTEGER; iQuo INTEGER; lLen CONSTANT INTEGER := 2;
BEGIN
iBas := length(vInp);
iQuo := iSeq;
WHILE iQuo > 0 LOOP
iRem := iQuo mod iBas;
--dbms_output.put_line('Now we divide ' || lpad(iQuo,lLen,'0') || ' by ' || lpad(iBas,lLen,'0') || ', yielding a quotient of ' || lpad( TRUNC(iQuo / iBas) ,lLen,'0') || ' and a remainder of ' || lpad(iRem,lLen,'0') || ' giving the char: ' || substr(vInp, iRem, 1)); end if;
iQuo := TRUNC(iQuo / iBas);
If iRem < 1 Then iRem := iBas; iQuo := iQuo - 1; End If;
vResult := substr(vInp, iRem, 1) || vResult;
END LOOP;
RETURN vResult;
END SEQGEN;
SQL ステートメントのみで記述します。
何かのようなもの:
WITH sequence ( vResult, lSeq ) AS
(
SELECT str, length(str) base FROM (SELECT 'abc' str FROM DUAL)
)
SELECT vResult FROM sequence WHERE lSeq < 13
if str = 'aB' output: if str = 'abC' output:
1 a a
2 B b
3 a a C
4 a B a a
5 B a a b
6 B B a C
7 a a a b a
8 a a B b b
9 a B a b C
10 a B B C a
11 B a a C b
12 B a B C C
13 B B a a a a
str = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' の場合:
SELECT vResult FROM sequence
WHERE vResult in ('0001','0002','0009','000A','000Z',
'0010','0011','001A','ZZZZ') --you get the idea...
Stackoverflow で、かなり関連性のある質問をいくつか見つけました。 SQL のみを使用した Base 36 から Base 10 への変換、および 関数を使用しない PL/SQL の base 変換。しかし、現在のSQLの知識では、これをハックすることはできません...
EDITED:
またはまあ、それはほとんどこのようなものです:
select sum(position_value) pos_val from (
select power(base,position-1) * instr('abc', digit) as position_value from (
select substr(input_string,length(input_string)+1-level,1) digit, level position, length(input_string) base
from (select 'cc' input_string from dual)
connect by level <= length(input_string)
)
)
pos_val をパラメーターとして指定し、input_string を取得したいことを除いて...