Kategori arşivi: Oracle

Oracle Genel Makaleler.

Oracle 12C Online Datafile Taşımak

Oracle 12C Online Datafile Taşımak

Bu makalede oracle 12C üzerinde online olarak(kesintisiz) datafile taşıması yapacağız,bu özellik sadece 12C veritabanı ile (gelen) kullanılabilen bir özellik, eski versiyonlarda(11G,10G,9i ..) çalışmayacaktır.Disk yetersizliği, diskin değişmesi, ASm’e migration gibi durumlarda datafileları move etmemiz gerekebilir.
Eski versiyonlarda nasıl taşınır bu konuya yazının sonunda kısaca değineceğim ama bunun için detaylı olarak makale yazmayı planlıyorum. Şimdi asıl konumuza dönelim, 12C’de online olarak datafile nasıl taşınır bakalım.

Kullanım amaçları;
– Datafile Rename
– ASM’den ASM’e taşıma
– ASM’den diske taşıma
– Diskten ASM’e taşıma

1. Diskten Diske Datafile Taşımak

Önce Datafilelarımızın lokasyonlarına bakalım.


SQL>Select name, STATUS  from v$datafile;

NAME                                                         STATUS
------------------------------------------------------------ ----------
/u01/12CDB/oradata/omertest/system01.dbf                    SYSTEM
/u01/12CDB/oradata/omertest/example01.dbf                   ONLINE
/u01/12CDB/oradata/omertest/sysaux01.dbf                    ONLINE
/u01/12CDB/oradata/omertest/undotbs01.dbf                   ONLINE
/u01/12CDB/oradata/omertest/test1.dbf                       ONLINE
/u01/12CDB/oradata/omertest/test2.dbf                       ONLINE
/u01/12CDB/oradata/omertest/users01.dbf                     ONLINE

7 rows selected.

Test1.dbf adlı datafile’ımızı aynı lokasyonda Rename edelim.(taşıyalım)


SQL> alter database move datafile
  2  '/u01/12CDB/oradata/omertest/test1.dbf '    
  3  to 
  4  '/u01/12CDB/oradata/omertest/omertest1.dbf ';

Database altered.

Datafileları tekrar kontrol edelim..


SQL>Select name, STATUS  from v$datafile;

NAME                                                         STATUS
------------------------------------------------------------ ----------
/u01/12CDB/oradata/omertest/system01.dbf                    SYSTEM
/u01/12CDB/oradata/omertest/example01.dbf                   ONLINE
/u01/12CDB/oradata/omertest/sysaux01.dbf                    ONLINE
/u01/12CDB/oradata/omertest/undotbs01.dbf                   ONLINE
/u01/12CDB/oradata/omertest/omertest1.dbf                   ONLINE
/u01/12CDB/oradata/omertest/test2.dbf                       ONLINE
/u01/12CDB/oradata/omertest/users01.dbf                     ONLINE

7 rows selected.

Ve işlem tamamdır, kesinti olmadan online olarak datafile’ı rename ve move edebildik.
Şimdi de ASM ve disk üzerindeki taşımalar için örnekler yapalım..

2. Diskten ASM’e Datafile Taşımak

Test için oluşturduğum iki datafile’ı local diskten +DATA üzerine taşıyalım..


SQL> alter database move datafile
  2  '/u01/12CDB/oradata/omertest/omertest1.dbf'
  3  to
  4  '+DATA/omertest/omertest1.dbf';

Database altered.

SQL> alter database move datafile
  2  '/u01/12CDB/oradata/omertest/test2.dbf'
  3  to 
  4  '+DATA/omertest/omertest2.dbf';

Database altered.

SQL> select name, STATUS  from v$datafile;

NAME                                                         STATUS
------------------------------------------------------------ ----------
/u01/12CDB/oradata/prod/system01.dbf                    SYSTEM
/u01/12CDB/oradata/prod/example01.dbf                   ONLINE
/u01/12CDB/oradata/prod/sysaux01.dbf                    ONLINE
/u01/12CDB/oradata/prod/undotbs01.dbf                   ONLINE
+DATA/omertest/omertest1.dbf                                 ONLINE
+DATA/omertest/omertest2.dbf                                 ONLINE
/u01/12CDB/oradata/omertest/users01.dbf                 ONLINE

7 rows selected.

3. ASM’den ASM’e Datafile Taşımak

Şimdi de test için oluşturduğum iki datafile’ı +RECO diskine taşıyalım..


SQL> alter database move datafile
  2  '+DATA/omertest/omertest1.dbf'
  3  to
  4  '+RECO/omertest/omertest1.dbf';

Database altered.

SQL> alter database move datafile
  2  '+DATA/omertest/omertest2.dbf'
  3  to 
  4  '+RECO/omertest/omertest2.dbf';

Database altered.

SQL> select name, STATUS  from v$datafile;

NAME                                                         STATUS
------------------------------------------------------------ ----------
/u01/12CDB/oradata/prod/system01.dbf                    SYSTEM
/u01/12CDB/oradata/prod/example01.dbf                   ONLINE
/u01/12CDB/oradata/prod/sysaux01.dbf                    ONLINE
/u01/12CDB/oradata/prod/undotbs01.dbf                   ONLINE
+RECO/omertest/omertest1.dbf                            ONLINE
+RECO/omertest/omertest2.dbf                            ONLINE
/u01/12CDB/oradata/omertest/users01.dbf                 ONLINE

7 rows selected.

4. ASM’den Diske Datafile Taşımak

ASM de bulunan test1 datafile’ı disk üzerine taşıyalım.


SQL> alter database move datafile
  2  '+DATA/omertest/omertest1.dbf'
  3  to
  4  '/u01/12CDB/oradata/omertestdata/omertest1.dbf';

Database altered.


SQL> select name, STATUS  from v$datafile;

NAME                                                         STATUS
------------------------------------------------------------ ----------
/u01/12CDB/oradata/prod/system01.dbf                    SYSTEM
/u01/12CDB/oradata/prod/example01.dbf                   ONLINE
/u01/12CDB/oradata/prod/sysaux01.dbf                    ONLINE
/u01/12CDB/oradata/prod/undotbs01.dbf                   ONLINE
/u01/12CDB/oradata/omertestdata/omertest1.dbf           ONLINE
+RECO/omertest/omertest2.dbf                            ONLINE
/u01/12CDB/oradata/omertest/users01.dbf                 ONLINE

7 rows selected.

Notlar:
*Online datafile taşıma oracle 12C ile gelen bir özelliktir, eski versiyonlarda bu özelliği kullanamayız.
*User datafilelartı taşıdığımız gibi system datafile’larını da taşıyabiliriz.
*Bu işlem yoğun kaynak kullanımı yapacağından günün sakin saatlerinde çalıştırmanız önerilir.
*Bu özellik için oracle’a çok teşekkürler 🙂

Oracle 12C öncesi datafile taşımak

12C öncesi datafile’ı kesintisiz taşımak mümkün değil minimum kesintiyle taşınabilir, bu durumda yapılması gereken işlemler kabaca aşağıdaki gibidir. Bu konuyu ayrıca bir makale olarak yazacağım, çünkü; system datafile’ları taşımak biraz daha farklı işlemler gerektiriyor ve instance’ı kapatıp açmanız gerekiyor..

Ama user datafile’lar 11G ve öncesi için aşağıdaki yöntemlerle taşınabilir..

– Seçenek 1
1.Tablespace’i offline yap.(alter tablespace x online)
2.Datafile’ı fiziksel olarak taşı ya da rename et(mv test1.dbf)
3.Controlfile’a datafile’ın yeni yerini bildir.(alter database rename file)
4.Tablespace’i online yap.(alter tablespace online)

-Seçenek 2
RMAN ile datafile’ın yeni kopyasına switch etmek.

Dbms_Output Paketi Ve Ekrana Deger Bastırma

Dbms_Output Paketi Ve Ekrana Deger Bastırma

Dbms_output paketi oracleda ekrana değer bastırmaya yarar ve değişkenlerin değerlerini görmemizi sağlar.Bu paketin source’u {ORACLE_HOME}/rdbms/admin/dbmsotpt.sql dizininde bulunuyor. sqlplus, toad, plsql developer gibi toollarda bu paketi kullanabiliriz.Toad ve plsql developer üzerinde zaten bulunuyor ve bir checkbox yardımıyla aktif ve pasif edilebiliyor ama sqlplusda maalesef açmak, kapamak,
buffer size vermek için komutlar yazmamız gerekli.

– DBMS_OUTPUT enable etmek.
SET SERVEROUTPUT ON;
ya da
exec dbms_output.enable;

– DBMS_OUTPUT disable etmek.
SET SERVEROUTPUT OFF;
ya da
exec dbms_output.disable;

– Buffer size set etmek (1-1.000.000 arası)
exec dbms_output.enable(1000000);

– Yeni satır açmak, boş bir satır bırakır.
dbms_output.new_line();

– dbms_output ile ekrana değer bastırmak
dbms_output.put_line();

DBMS_OUTPUT Paketi kullanımı ile ilgili örnekler:

1- Sistem tarihini dbms_output.put_line ile ekrana bastıralım.

SQL> BEGIN
2 dbms_output.put_line(to_char(SYSDATE,'DD-MM-YYYY HH24:MI:SS'));
3 END;
4 /
27-11-2015 15:46:57

PL/SQL procedure successfully completed.

2- Kullanıcı tablo sayısını dbms_output.put_line ile ekrana bastıralım.

SQL> set serveroutput on;
SQL> BEGIN
2 FOR REC_ IN (SELECT K.OWNER, COUNT(1) SAY
3 FROM ALL_TABLES K
4 GROUP BY K.OWNER
5 ORDER BY 1) LOOP
6 DBMS_OUTPUT.PUT_LINE(REC_.OWNER || ' in tablo sayisi = ' || REC_.SAY);
7 END LOOP;
8 END;
9 /

APEX_030200 in tablo sayisi = 360
APPQOSSYS in tablo sayisi = 4
CTXSYS in tablo sayisi = 50
DBSNMP in tablo sayisi = 25
EXFSYS in tablo sayisi = 47
MDSYS in tablo sayisi = 129
OLAPSYS in tablo sayisi = 126
ORDDATA in tablo sayisi = 73
ORDSYS in tablo sayisi = 5
OUTLN in tablo sayisi = 3
SYS in tablo sayisi = 1013
SYSMAN in tablo sayisi = 728
SYSTEM in tablo sayisi = 169

PL/SQL procedure successfully completed.

3-) Döngü değerini dbms_output.put_line ile ekrana bastıralım.

SQL> set serveroutput on;
SQL> declare
1 dummy number;
2 begin
3 for i in 1..10 loop
4 dbms_output.put_line('i nin degeri='||i);
5 end loop;
6 end;
7 /

i nin degeri=1
i nin degeri=2
i nin degeri=3
i nin degeri=4
i nin degeri=5
i nin degeri=6
i nin degeri=7
i nin degeri=8
i nin degeri=9
i nin degeri=10

PL/SQL procedure successfully completed.

Umarım faydalı olur..

Oracle Password Verify Function

Oracle Password Verify Function

Kullanıcı şifrelerinin komplex şifreler olması güvenlik açısından çok önemli bir konudur.Kullanıcı şifrelerini kontrol etmek için password verify fonksiyonunu kullanabiliriz.Bu fonksiyon sys scheması altında oluşturulur ve şifre değiştirme işleminde yeni şifreyi kontrol ederek gereksinimleri karşılayıp karşılamadığını kontrol eder.Dosyayı text editörle açıp içine bakabilirsiniz. username ve şifre aynı olamaz,en az 8 karakter olmalı, en az bir harf ve sayı içermeli vb kontrolleri bizim yerimize yapacaktır.

Bu fonskiyon 3 tane parametre (username,new pass,old_pass) alıp boolean değer(mantıksal true ya da false) döndürür.Oracle ın default Password Verify fonksiyonunu oracle home altında $ORACLE_HOME/rdbms/admin/utlpwdmg.sql ismiyle bulabilirsiniz.Utlpwdmg.sql dosyasını sqlplustan çalıştıralım. İstersek üzerinde editleme yaparak kendi kontrollerimizi ekleyip tekrar compile edebiliriz.

SQL> @/oracle/app/product/11.2.0.4/db/rdbms/admin/utlpwdmg.sql
Function created.
Grant succeeded.
Profile altered.
Function created.
Grant succeeded.

Çalıştırdık ve fonksiyonumuz compile edildi, artık kullanabiliriz.Fonksiyonumuzu doğrudan kullanıcılarla ilişkilendiremiyoruz, kullanıcıları sınıflandırdığımız profile denen oracle nesnelerine atama yapacağız, ve böylece o profildeki her userın şifre değişikliği bu fonksiyonla denetlenmiş olacak.

Örneğin DEVELOPER_PROFILE diye bir profilimiz olsun, ve bu profile dahil olan userların (developerların) şifre değişikliklerini fonksiyonumuzla kontrol etmek isteyelim.Bunun için profile fonksiyonumuzu atamamız gerekiyor.

SQL> Alter profile DEVELOPER_PROFILE limit password_verify_function verify_function_11G;

Artık bu profildeki her userın şifre değişikliği fonksiyonumuzla kontrol edilecektir.

Geri almak istersek NULL diyip aynı komutu çalıştıabiliriz.

SQL> Alter profile DEVELOPER_PROFILE limit password_verify_function NULL;

Hangi usera hangi profile atanmış aşağıdaki sorgu ile görebiliriz.

SQL> SELECT USERNAME, PROFILE FROM DBA_USERS ORDER BY 2,1;

Umarım faydalı olur.

Redo Log Switch Sıklığı

Redo Log Switch Sıklığı

Redo LOG dosyalarının switch sıklığı bize database’imizin hangi saat aralıklarında daha yoğun kullanıldıgına dair ipucu verir. İdeal switch etme sıklığı 15-20 dk olmalıdır. Redo log dosyalarının boyutları da bu konuda önem arzediyor, database’e göre küçük kalan redo LOG dosyaları daha çok switch edecektir, ve redo waitlere sebep olacaktır. Redo logların büyük size’lı olması da instance recovery(SMON Processi açılışta otomatik olarak yapar) süresini uzatacaktır. Redo logların yeniden boyutlandırılması ile ilgili başka bir yazı yazacağım.

Şimdi redo log dosyalarının günlük switch sıklığı ile ilgili bilgi alacağımız bir sorgu yazalım.

select
to_char(first_time,'YYYY-MM-DD') DATED,
to_char(first_time,'DAY') DAY,
to_char(sum(decode(to_char(first_time,'HH24'),'00',1,0)),'999') "00",
to_char(sum(decode(to_char(first_time,'HH24'),'01',1,0)),'999') "01",
to_char(sum(decode(to_char(first_time,'HH24'),'02',1,0)),'999') "02",
to_char(sum(decode(to_char(first_time,'HH24'),'03',1,0)),'999') "03",
to_char(sum(decode(to_char(first_time,'HH24'),'04',1,0)),'999') "04",
to_char(sum(decode(to_char(first_time,'HH24'),'05',1,0)),'999') "05",
to_char(sum(decode(to_char(first_time,'HH24'),'06',1,0)),'999') "06",
to_char(sum(decode(to_char(first_time,'HH24'),'07',1,0)),'999') "07",
to_char(sum(decode(to_char(first_time,'HH24'),'08',1,0)),'999') "08",
to_char(sum(decode(to_char(first_time,'HH24'),'09',1,0)),'999') "09",
to_char(sum(decode(to_char(first_time,'HH24'),'10',1,0)),'999') "10",
to_char(sum(decode(to_char(first_time,'HH24'),'11',1,0)),'999') "11",
to_char(sum(decode(to_char(first_time,'HH24'),'12',1,0)),'999') "12",
to_char(sum(decode(to_char(first_time,'HH24'),'13',1,0)),'999') "13",
to_char(sum(decode(to_char(first_time,'HH24'),'14',1,0)),'999') "14",
to_char(sum(decode(to_char(first_time,'HH24'),'15',1,0)),'999') "15",
to_char(sum(decode(to_char(first_time,'HH24'),'16',1,0)),'999') "16",
to_char(sum(decode(to_char(first_time,'HH24'),'17',1,0)),'999') "17",
to_char(sum(decode(to_char(first_time,'HH24'),'18',1,0)),'999') "18",
to_char(sum(decode(to_char(first_time,'HH24'),'19',1,0)),'999') "19",
to_char(sum(decode(to_char(first_time,'HH24'),'20',1,0)),'999') "20",
to_char(sum(decode(to_char(first_time,'HH24'),'21',1,0)),'999') "21",
to_char(sum(decode(to_char(first_time,'HH24'),'22',1,0)),'999') "22",
to_char(sum(decode(to_char(first_time,'HH24'),'23',1,0)),'999') "23"
from v$log_history
where trunc(first_time) > trunc(sysdate-7) and trunc(first_time) <= trunc(sysdate)
group by to_char(first_time,'YYYY-MM-DD'),to_char(first_time,'DAY')
order by 1 desc;

Sonucumuz(RAC ortamlarda tüm instanceler gelir)

DATED	DAY	00	01	02	03	04	05	06	07	08	09	10	11	12	13	14	15	16	17	18	19	20	21	22	23
2015-06-11	THURSDAY 	  16	  34	  18	  12	  17	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  14	  14	  12	  17	  25	  52
2015-06-10	WEDNESDAY	  15	  33	  17	  12	  19	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  14	  12	  15	  17	  26	  53
2015-06-09	TUESDAY  	  22	  52	  25	  28	  15	  13	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  14	  12	  16	  18	  26	  48
2015-06-08	MONDAY   	  12	  12	  12	  12	  13	  12	  12	  12	  12	  32	  12	  12	  12	  15	  12	  12	  12	  12	  14	  12	  16	  16	  24	  12
2015-06-07	SUNDAY   	  12	  12	  14	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  14	  12	  12	  12	  12	  12
2015-06-06	SATURDAY 	  32	  31	  20	  13	  17	  12	  13	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  12	  14	  12	  12	  12	  12	  12

Redo loglarla ilgili bilgi alabileceğimiz diğer viewler;

--Arşive çıkmış log bilgileri
SELECT * FROM v$archived_log k ORDER BY k.first_time DESC;

--Genel redo log bilgileri(size, status vb)
SELECT * FROM v$log;

--Redo log dizinleri
SELECT * FROM v$logfile;

-- Redo log history
SELECT * FROM v$log_history

 

AUD$ ve FGA_LOG$ tablolarını başka tablespace’e taşımak

AUD$ ve FGA_LOG$ tablolarını başka tablespace’e taşımak

AUD$ ve FGA_LOG$( fine-grained audit) tabloları default olarak system tablespace’inde oluşturulur,zamanla loglar şiştikçe system tablespacei büyüyecektir.Bu yüzden bu tabloları başka bir tablespace’e taşımak gerekir.

* Tablolar hangi tablespacede kontrol edelim.

SELECT table_name, tablespace_name FROM dba_tables
WHERE table_name IN ('AUD$', 'FGA_LOG$') ORDER BY table_name; 2

TABLE_NAME  TABLESPACE_NAME
------------------------------ ------------------------------
AUD$        SYSTEM
FGA_LOG$    SYSTEM

* Yeni Tablespace ekleyelim.

Tablolarımızı barındıracak yeni bir tablespace create edelim.Oluşturacağımız datafile’ın mevcut AUD$ ve FGA_LOG$ tablosunu alabilecek boyutta olduğuna emin olalım.(500 MB verdim)

Create tablespace tbs_audit datafile '/u01/app/oracle/oradata/testdb/tbs_audit1.dbf' size 500M autoextend on;

Tablespace created.

* AUD$, FGA_LOG$ Tablolarımızı move edelim.

A-) DBMS_AUDIT_MGMT paketi ile taşımak.(Oracle 11G R2 ile gelen özelliktir..)

BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, --AUD$ tablosu taşınır.
audit_trail_location_value => 'TBS_AUDIT');
END;
/
PL/SQL procedure successfully completed.

BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD, --FGA_LOG$ tablosu taşınır.
audit_trail_location_value => 'TBS_AUDIT');
END;
/
PL/SQL procedure successfully completed.

B-) Alter table Move komutu ile taşımak.(11G R2 öncesi)

BEGIN
alter table sys.aud$ move tablespace tbs_audit;
alter table sys.aud$ move lob(sqlbind,sqltext) store as lobsegment (tablespace tbs_audit);
alter index SYS_IL0000000376C00041$$ rebuild online tablespace tbs_audit;
alter index SYS_IL0000000376C00040$$ rebuild online tablespace tbs_audit;

alter table sys.fga_log$ move tablespace tbs_audit;
alter table sys.fga_log$ move lob(sqlbind,sqltext) store as lobsegment (tablespace tbs_audit);
alter index SYS_IL0000000386C00028$$ rebuild online tablespace tbs_audit;
alter index SYS_IL0000000386C00013$$ rebuild online tablespace tbs_audit;

END;
/

* Tabloların yeni tablespacelerini kontrol edelim.

SELECT table_name, tablespace_name FROM dba_tables
WHERE table_name IN ('AUD$', 'FGA_LOG$') ORDER BY table_name; 2

TABLE_NAME    TABLESPACE_NAME
------------------------------ ------------------------------
AUD$              TBS_AUDIT
FGA_LOG$          TBS_AUDIT

Oracle User Password History

ORACLE USER PASSWORD HISTORY

Bir Oracle USERının şifre değişim geçmişini ve son şifre değişiklik tarihini görmemiz mümkün.
SYS aşağıdaki history tablosunda bulunmuyor, onun dışındakileri sorgulayabiliriz.

Şifre değişim tarihleri.

SELECT USER$.USER#, USER$.NAME, USER_HISTORY$.PASSWORD_DATE
  FROM SYS.USER$, SYS.USER_HISTORY$
 WHERE USER$.USER# = USER_HISTORY$.USER#
   AND NAME IN ('SYSMAN', 'DBSNMP')
 ORDER BY 1, 2 DESC;

Son şifre değiştirdiği tarih:

SELECT NAME, CTIME CREATION_DATE, PTIME LAST_PASS_CHANGE_DATE
  FROM SYS.USER$
 WHERE NAME IN ('SYSMAN', 'DBSNMP')
 ORDER BY 1, 2, 3

Oracle default sifreleri tespit etmek ve degistirmek

Oracle DEFAULT şifreleri tespit etmek ve değiştirmek

Bildiğiniz gibi DATABASE CREATE ederken SYS,SYSTEM,dbsnmp,sysman şifrelerini giriyoruz.
Peki ya diğer kullanıcılar? Diğer kullanıcılar DEFAULT passwordleriyle oluşturulur.Bu bir
güvenlik açığıdır.Bu yüzden bu kullanıcları kontrol edip yeni şifre atamalıyız.

Hangi kullanıcılar DEFAULT şifreli kontrol edelim..

SELECT * FROM dba_users_with_defpwd;
XS$NULL
MDSYS
SPATIAL_WFS_ADMIN_USR
OUTLN
CTXSYS
OLAPSYS
SPATIAL_CSW_ADMIN_USR
OWBSYS
HR
ORACLE_OCM
EXFSYS
SCOTT
ORDSYS
ORDPLUGINS
MDDATA
PM
APPQOSSYS
XDB
ORDDATA
IX
BI
WMSYS
SI_INFORMTN_SCHEMA

Default şifreleri değiştirelim..
Kullanılan userlar için özel şifre verebilirsiniz..

ALTER USER BI IDENTIFIED BY "YeniŞifre";

Ben kullanmadığımız userlara random şifre veriyorum.
Bunun için br plsql bloğu yazıp SYS ile çalıştıralım..

DECLARE
stmt_ VARCHAR2(200);
BEGIN 
  FOR rec_ IN( SELECT * FROM dba_users_with_defpwd ) LOOP
     stmt_:= 'ALTER USER '||rec_.username||' IDENTIFIED BY ' ||DBMS_RANDOM.STRING('a', 10);
     dbms_output.put_line(RPAD(rec_.username,30)||' ICIN SIFRE DEGISIKLIGI >  '||stmt_); 
     EXECUTE IMMEDIATE stmt_;     
  END LOOP;
END;

DBMS_RANDOM.STRING(‘a’, 10) fonksiyonu ile Büyük-küçük harf ve sayı kombinasyonu
oluşturabilirsiniz..

Umarım faydalı olur..