Dynamicky zřetězení řetězců pomocí smyčky v Oracle PL/SQL

0

Otázka

Byl jsem se snaží standardizovat "Adresa" pole tabulky s 400k linky. Problém je, že této oblasti byla provedena, aby se volné pole formuláře, což znamená, že uživatelé (po registraci) mohli vstoupit jen něco chtěli, do. Již se mi podařilo rozdělit tuto adresu pole do 14 ostatní se každé slovo z adresy řádku v pořadí.

Teď jsem třeba zřetězit některé z těchto polí dohromady do různých oblastech, jako jsou:

  • Název Ulice
  • Číslo Domu

Kéž by to bylo tak jednoduché, jak popadl první 3 pole a volat, že název ulice a 4. pole jako číslo Domu, ale v důsledku různých název ulice délky, pole "číslo domu" je obvykle pole, #4, #5 a jen zřídka kdy #3 a #6.

Už jsem si myslel, že o přístup, který by mohl fungovat v tomto případě, a to by bylo zřetězení těchto oblastech ve smyčce a pomocí první výskyt pole, kde jeho první číslice je číslo jako bod zlomu.(vzhledem k některé domy jsou číslovány "10C", "1A", "1B" a tak dále)

Vzhledem k ne ne velmi dobrý v PL/SQL, já nevím, jak dát tuto myšlenku do kódu.

Vše, co jsem dokázal, tak daleko, bylo psaní funkce pro kontrolu, zda řetězec začíná číslicí nebo ne, takže to by mohl být použit ve funkci if.

Jak mohu dynamicky "procházet" pole ve smyčce pomocí PL/SQL? Bych použít pole? Je to vůbec možné?

EDIT: Příklady toho, co toto pole adresa obsahuje (v portugalštině):

Avenida Doutor Theomário Pinto da Costa 450 Condominio Renesance, rua 1, casa 1

Rua Álvaro Peres Filho, 60 Casa azul em frente ao orelhão

Travessa Delegado Zé Lima 61 antiga Praça Rio Branco

Rua Finlândia 28 Qd 111

Alameda Áustria 107 Condomínio Jardim Europa Já

Tam je jasný vzor v datech, což mě vede k tomu, že tato adresa dat bylo odebráno v děleném formátu, ale pak spojeny do jediného pole tabulky. Co musím udělat, je, naopak, v podstatě.

Vzor pokračuje:

Avenida(1) Doutor Theomário Pinto da Costa (2) 450(3) Condominio Renaissance, rua 1, casa 1(4)

1 = typ Ulici (avenue, ulici a atd.)

2 = Název Ulice

3 = Číslo Domu

4 = Reference (obvykle použit na pomoc s pokyny, toto pole je obvykle otevřený design. Věci, jako je Patro, budova a Byt jméno jde zde.)

Jak můžete vidět z výše uvedených příkladů, ulice mají obvykle widly různých název délek, což umožňuje nastavení konkrétní počet polí jako název ulice nemožné.

gis oracle plsql sql
2021-11-19 18:29:34
1

Nejlepší odpověď

1

A možné řešení:

Declare
  /* Dynamically concatenating strings using a loop in Oracle PL/SQL */
  --
  type tyArray_parsed
  is table of varchar2(2000)
  index by binary_integer;
  --
  arAddress_parsed   tyArray_parsed;
  --
  cnuSTREET_TYPE   constant integer:=1;
  cnuSTREET_NAME   constant integer:=2;
  cnuHOUSE_NUMBER  constant integer:=3;
  cnuREFERENCE     constant integer:=4;
  --
  Procedure print(p_isbTexto varchar2)
  is
    nuIzq_print  integer;
    nuDer_print    integer;
  Begin
    nuDer_print:=0;
    Loop
       nuIzq_print:=nuDer_print+1;
       nuDer_print:=instr(p_isbTexto,chr(10),nuIzq_print);
       exit when nvl(nuDer_print,0)=0;
       dbms_output.put_line(substr(p_isbTexto, nuIzq_print, nuDer_print-nuIzq_print));
    End loop;
    dbms_output.put_line(substr(p_isbTexto, nuIzq_print));
  End print;
  --
  procedure pAddress_split(isbAddress_string      varchar2,
                           oarAddress_parsed  out tyArray_parsed
                          )
  is
    type tyArray_string
    is table of varchar2(2000)
    index by binary_integer;
    --
    arFields  tyArray_string;
    nuLeft_pos    integer;
    nuRight_pos  integer;
    nuMy_number   number;
    blIs_number   boolean;
    nuStep        integer;
  Begin
    print('---------------------------------------');
    print('isbAddress_string=['||isbAddress_string||']');
    --
    nuRight_pos:=0;
    Loop
       nuLeft_pos:=nuRight_pos+1;
       nuRight_pos:=instr(isbAddress_string,' ',nuLeft_pos);
       exit when nvl(nuRight_pos,0)=0;
       arFields(arFields.COUNT+1):=substr(isbAddress_string,
                                          nuLeft_pos,
                                          nuRight_pos-nuLeft_pos
                                         );
    End loop;
    arFields(arFields.COUNT+1):=substr(isbAddress_string,
                                       nuLeft_pos
                                      );
    print('arFields.COUNT='||arFields.COUNT);
    --
    For nuI in arFields.FIRST..arFields.LAST loop
        print(lpad(nuI,4)||'['||arFields(nui)||']');
    End loop;
    --
    nuStep:=cnuSTREET_TYPE;
    For nuI in arFields.FIRST..arFields.LAST loop
       if nuStep=cnuSTREET_TYPE then
          oarAddress_parsed(cnuSTREET_TYPE):=arFields(nui);
          nuStep:=cnuSTREET_NAME;
       Elsif nuStep=cnuSTREET_NAME then
             blIs_number:=false;
             Begin
               nuMy_number:=to_number(arFields(nui));
               blIs_number:=true;
             Exception
               when others then
                     blIs_number:=false;
             End;
             if blIs_number then
                oarAddress_parsed(cnuHOUSE_NUMBER):=arFields(nui);
                nuStep:=cnuREFERENCE;
             Else
                if not(oarAddress_parsed.exists(cnuSTREET_NAME)) then
                   oarAddress_parsed(cnuSTREET_NAME):=arFields(nui);
                Else
                   oarAddress_parsed(cnuSTREET_NAME):=oarAddress_parsed(cnuSTREET_NAME)||' '||arFields(nui);
                End if;
             End if;
      Elsif nuStep=cnuREFERENCE then
            if not(oarAddress_parsed.exists(cnuREFERENCE)) then
               oarAddress_parsed(cnuREFERENCE):=arFields(nui);
            Else
               if arFields(nui)=',' then
                  oarAddress_parsed(cnuREFERENCE):=oarAddress_parsed(cnuREFERENCE)||arFields(nui);
               Else
                  oarAddress_parsed(cnuREFERENCE):=oarAddress_parsed(cnuREFERENCE)||' '||arFields(nui);
               end if;
            End if;
      End if;
    End loop;
    --
    for nuI in oarAddress_parsed.FIRST..oarAddress_parsed.LAST loop
        print(lpad(nuI,2)||'|['||oarAddress_parsed(nui)||']');
    End loop;
  End pAddress_split;
Begin
  dbms_application_info.set_module('Split','START-'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
  --
  pAddress_split('Avenida Doutor Theomário Pinto da Costa 450 Condominio Renaissance, rua 1, casa 1',arAddress_parsed);
  pAddress_split('Rua Álvaro Peres Filho 60 Casa azul em frente ao orelhão',arAddress_parsed);
  pAddress_split('Travessa Delegado Zé Lima 61 antiga Praça Rio Branco',arAddress_parsed);
  pAddress_split('Rua Finlândia 28 Qd 111',arAddress_parsed);
  pAddress_split('Alameda Áustria 107 Condomínio Jardim Europa I',arAddress_parsed);
  --
  --
  dbms_application_info.set_module('Split','END-'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
End;
/

Odpověď:

---------------------------------------
isbAddress_string=[Avenida Doutor Theomário Pinto da Costa 450 Condominio Renaissance, rua 1, casa 1]
arFields.COUNT=13
   1[Avenida]
   2[Doutor]
   3[Theomário]
   4[Pinto]
   5[da]
   6[Costa]
   7[450]
   8[Condominio]
   9[Renaissance,]
  10[rua]
  11[1,]
  12[casa]
  13[1]
 1|[Avenida]
 2|[Doutor Theomário Pinto da Costa]
 3|[450]
 4|[Condominio Renaissance, rua 1, casa 1]
---------------------------------------
isbAddress_string=[Rua Álvaro Peres Filho 60 Casa azul em frente ao orelhão]
arFields.COUNT=11
   1[Rua]
   2[Álvaro]
   3[Peres]
   4[Filho]
   5[60]
   6[Casa]
   7[azul]
   8[em]
   9[frente]
  10[ao]
  11[orelhão]
 1|[Rua]
 2|[Álvaro Peres Filho]
 3|[60]
 4|[Casa azul em frente ao orelhão]
---------------------------------------
isbAddress_string=[Travessa Delegado Zé Lima 61 antiga Praça Rio Branco]
arFields.COUNT=9
   1[Travessa]
   2[Delegado]
   3[Zé]
   4[Lima]
   5[61]
   6[antiga]
   7[Praça]
   8[Rio]
   9[Branco]
 1|[Travessa]
 2|[Delegado Zé Lima]
 3|[61]
 4|[antiga Praça Rio Branco]
---------------------------------------
isbAddress_string=[Rua Finlândia 28 Qd 111]
arFields.COUNT=5
   1[Rua]
   2[Finlândia]
   3[28]
   4[Qd]
   5[111]
 1|[Rua]
 2|[Finlândia]
 3|[28]
 4|[Qd 111]
---------------------------------------
isbAddress_string=[Alameda Áustria 107 Condomínio Jardim Europa I]
arFields.COUNT=7
   1[Alameda]
   2[Áustria]
   3[107]
   4[Condomínio]
   5[Jardim]
   6[Europa]
   7[I]
 1|[Alameda]
 2|[Áustria]
 3|[107]
 4|[Condomínio Jardim Europa I]
2021-11-23 03:27:13

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................