Bu sayfa makine çevirisidir. İngilizce orijinalini okuyun. English

IBSurgeon kütüphanesi

Firebird saklı prosedürü, satırı ayraçlarla bölerek kayıt kümesine dönüştürür.

Bu, Firebird PSQL üzerinde çalışan her geliştiricinin er ya da geç karşılaştığı görevlerden biridir - sınırlayıcılar içeren bir satırı ayrı değerler dizisine nasıl böleriz? Şöyle bir şey:

Code

select * from sp_split_into_words('foo rio bar firebird,mysql,postgresql;mssql;redis/rty');

Çıktı:
######

WORD
==========
foo
rio
bar
firebird
mysql
postgresql
mssql
redis
rty

Bunu saf SQL ile yapmak mümkündür - lütfen aşağıdaki saklı prosedür kodunu kullanın, yazarı Pavel Zotov, Firebird QA mühendisi ve IBSurgeon baş DBA’sıdır.

Lütfen bu prosedürün boşluk dahil geniş bir olası sınırlayıcı listesi içerdiğini unutmayın, bu nedenle yalnızca virgül veya noktalı virgüle ihtiyacınız varsa, diğer sınırlayıcıları a_del değişkeninden kaldırabilirsiniz.

Ayrıca, döndürülen varchar boyutuna (return değişkeni word) dikkat edin - varsayılan olarak varchar(50)‘dir, ihtiyaçlarınıza göre ayarlayabilirsiniz.

Code
set term ^;
create or alter procedure sp_split_into_words(
    a_text varchar(2048) character set utf8,
    a_dels varchar(20) default ',.<>/?;:''"[]{}`~!@#$%^&*()-_=+\|/',
    a_special char(1) default ' '
)
returns (
  word varchar(50)
) as
begin
-- Yalnızca oltp_data_filling.sql içinde PATTERNS tablosunu doldurmak için kullanılan yardımcı SP
-- SIMILAR TO testinde kullanılacak kelimelerin çeşitli kombinasyonlarıyla.
for
    with recursive
    j as( -- döngü #1: sınırlayıcı listesini satırlara dönüştür
        select s,1 i, substring(s from 1 for 1) del
        from(
          select replace(:a_dels,:a_special,'') s
          from rdb$database
        )

        UNION ALL

        select s, i+1, substring(s from i+1 for 1)
        from j
        where substring(s from i+1 for 1)<>''
    )

    ,d as(
        select :a_text s, :a_special sp from rdb$database
    )
    ,e as( -- döngü #2: her sınırlayıcıyı `boşluk` ile değiştir
        select d.s, replace(d.s, j.del, :a_special) s1, j.i, j.del
        from d join j on j.i=1

        UNION ALL

        select e.s, replace(e.s1, j.del, :a_special) s1, j.i, j.del
        from e
        -- nb: burada 'column unknown: e.i' hatası 2.5'in eski sürümlerinde oluşur,
        -- örn: WI-V2.5.2.26540 (Alexey Kovyazin'den mektup, 24.08.2014 14:34)
        join j on j.i = e.i + 1
    )
    ,f as(
        select s1 from e order by i desc rows 1
    )

    ,r as ( -- döngü #3: metni tek tek kelimelere böl
        select iif(t.k>0, substring(t.s from t.k+1 ), t.s) s,
             iif(t.k>0,position( del, substring(t.s from t.k+1 )),-1) k,
             t.i,
             t.del,
             iif(t.k>0,left(t.s, t.k-1),t.s) word
        from(
          select f.s1 s, d.sp del, position(d.sp, s1) k, 0 i from f cross join d
        )t

        UNION ALL

        select iif(r.k>0, substring(r.s from r.k+1 ), r.s) s,
             iif(r.k>0,position(r.del, substring(r.s from r.k+1 )),-1) k,
             r.i+1,
             r.del,
             iif(r.k>0,left(r.s, r.k-1),r.s) word
        from r
        where r.k>=0
    )
    select word from r where word>''
    into
        word
do
    suspend;
end
^
set term ;^
commit;