1 Mart 2011 Salı

C# Oracle Stored Procedure kullanimi


OracleCommand comm = new OracleCommand();
 'Yeni command nesnesi tanımlıyoruz
comm.CommandText = "procedure_adı"; 
'Prosedürümüzün adını buraya yazıyoruz
comm.Connection = conn; 
'Command Connection ı conn nesnemize eşitliyoruz
comm.CommandType = CommandType.StoredProcedure;
 'Komut tipinin s.prosedür olduğunu belirtiyoruz.
 
Aşağıda ise oracle stored procedure e göndereceğimiz değerleri ve geri dönecek değeri belirtiyoruz
 
comm.Parameters.Add("personelid", OracleType.VarChar, 2000).Value = değer;
comm.Parameters["personelid"].Direction = ParameterDirection.Input;
comm.Parameters.Add("personeladi", OracleType.VarChar, 2000).Value = değer;
comm.Parameters["personeladi"].Direction = ParameterDirection.Input;
comm.Parameters.Add("personelsoyadi", OracleType.VarChar, 2000).Direction = 
ParameterDirection.Output;   
'geri dönecek değer
comm.ExecuteNonQuery();
output = comm.Parameters["personelsoyadi"].Value.ToString();
 
OracleConnection conn = new OracleConnection(connStr);
OracleParameter param1 = new OracleParameter();
param1.ParameterName = "personelid";
param1.OracleType = OracleType.VarChar;
param1.Size =2000;
param1.Direction = ParameterDirection.Input;
param1.Value=değer;
OracleParameter param2 = new OracleParameter();
param2.ParameterName = "personeladi";
param2.OracleType = OracleType.VarChar;
param2.Direction = ParameterDirection.Input;
param2.Size = 2000;
param2.Value=değer;
OracleParameter param3 = new OracleParameter();
param2.ParameterName = "personelsoyadi";
param2.OracleType = OracleType.VarChar;
param2.Direction = ParameterDirection.Output;
param2.Size = 2000;
OracleParameter[] oraParams = new OracleParameter[] { param1, param2 };
OracleCommand cmd = new OracleCommand(“PROCEDURE_ADI”, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(oraParams);
conn.Open();
object result = cmd.ExecuteScalar();
conn.Close();
 
</div>
 
Yukardaki işlemle Oracle Veritabanında bulunan procedure_adı adındaki procedure 
‘i Asp.net C# ile kullanmış olduk.Kullandığımız procedure’in kodları ise;
 
<div id="codeview">
CREATE OR REPLACE PROCEDURE PROCEDURE_ADI
(personelid in varchar,personeladi in varchar,personelsoyadi IN OUT varchar) IS
BEGIN
SELECT psoyadi into personelsoyadi  FROM personel 
WHERE pid= "||personelid||" and padi= "||personeladi||"
END PROCEDURE_ADI;   /
</div>
 
Dikkat etmemiz gereken nokta biz burada input ve output değerlerini OracleType.VarChar olarak  belirledik.Eğer OracleType.VarChar olarak belirlediğimiz değerlere “size” değeri atamazsak
“No size set for variable length data type: String”
hatası ile karşılaşırız.Bu hata ile karşılaşmamak için OracleType.VarChar tipindeki verimizin Size ına  değer belirtmeliyiz
 
Share:

28 Aralık 2010 Salı

Oracle shared server opsiyonu ve IFS

Geçenlerde, IFS ERP uzmanı olarak çalışmaya devam eden arkadaşlarımdan birisi aradı.
Garip bir sorunundan bahsetti.

Problem oluşan sistem özellikleri
----------------------------------------
windows 2008 server 32 bit
8 gb ram
100+ acık kullanıcı connection
vs.

Problem Açıklaması
----------------------------------------
Database e belirli bir sayı üstü kullanıcı bağlandığında sistem yeni connection isteklerine
cevap vermiyormuş. Ta ki bazı connectionlar kapatılıncaya kadar.
Bu sorun oluştuğu anda ise sistem ram inin 2.6 gb gibi bir kısmı yani yarıdan az kısmı kullanılıyormuş.


Hımmm.

Oracle database e bağlanma sürecine biraz daha yakından bakacak olursak;

Oracle listener, her dedicated session için server tarafında bir dedicated server process
oluşturur(veya oluşturmaya çalışır). Bu oluşturulan process belirli miktarda bellek kullanır.
32 bit işletim sistemlerinde oracle, 2.5-3 gb civarının üstünde ram
kullanamadığından bu sorun oluşuyor. (2.5 - 3 gb den fazla ram kullanamama sorunu,
oracle dan değil 32 bit mimariden kaynaklanıyor yanlış anlaşılmasın )

Şimdi bir kere en iyi çözüm 64 bit işletim sistemine oracle kurmak ve gerekiyorsa sisteme ram eklemek.
Sonrada gerekli Oracle memory parametrelerini set etmek.

İkinci en iyi çözüm shared server opsiyonunu aktifleştirmek. Çünkü bu şekilde
her yeni connection için yeni bir dedicated server açılmayacak. Dolayısıyla memory
dolmayacak. Ama yoğun data kullanan kullanıcıların biraz daha yavaş çalışması duruma göre söz konusu.

Peki IFS ortamında nasıl yaparız bu
oracle shared server ı aktifleştirme işini?
------------------------------------------
1) Server parametrelerinde değişiklikler

alter system set shared_servers=10;
alter system set dispatchers='(PROTOCOL=TCP)';

Yukarıdaki sql statement lerini çalıştırdıktan bir süre sonra tns yöntemi dışı tüm bağlantılar
shared olmaya başlayacaktır.

Bu durumu aşağıdaki query ile de inceleyebilirsiniz.
SERVER sütünu SHARED ve NONE olan bağlantılar shared bağlantılardır.

select username,server from v$session order by server desc

Oracle parametrelerini burada sadece memory ye set ettik yani
database restart ında shared server konfigurasyonumuz yok olacak.
Parametrelerin kalıcı olması için testlerin ardından parametre dosyası güncellenebilir.

2) Client tarafında değişiklikler

IFS teki(Centura desek daha doğru) bağlantı tanımları runtime klasörü altındaki sql.ini dosyasından yapılıyor.
Bu dosya içerisinde, [oragtwy] tiketi altındaki remotedbname değerleri
bizim database bağlantılarımız.Örneğin sql.ini dosyamız aşağıdaki gibi olsun.

[oragtwy]
longbuffer=32760
fetchrow=20
maperror=OFF
substitute=SYSSQL.,
remotedbname=gercek,@//bizim_server_name_veya_ip:1521/bizim_sid

yukarıdaki 1. adımdaki server parametreleri set edildikten sonra,
buradaki "gercek" bağlantısından bağlanan tüm yeni client bağlantıları,
shared server connection u açarlar.

Burada bir sorun var .Tüm kullanıcı bağlantıları shared oldu. Fakat ben
bazı kullanıcılarımın performans açısından shared değil dedicated bağlanmasını
istiyorum diyebilirsiniz.

İşte bunu sağlayabilmek için sql.ini dosyasındaki, remotedbname imizi aşağıdaki
gibi değiştirmeliyiz.

remotedbname=gercek,@//bizim_sid

Buradaki bizim_sid, tnsnames.ora dosyasındaki tns ismidir.

Bu noktadan sonra bağlantının shared veya dedicated olması oracle client tnsnames dosyasına bağlıdır.

Dedicated için, aşağıdaki gibi bir tnsnames.ora tanımlaması olabilir.
Burada "SERVER=dedicated" olan bölümü "SERVER=shared" yaparsak bağlantı shared oluşturulmaya çalışılır..
Böylece her kullanıcıya, kendini bilgisayarıdaki tnsnames.ora da gerekli ayarları yaparak,
shared mı yoksa dedicated mı bağlantı yapacağı tanımlanabilir.

bizim_sid=
(DESCRIPTION=
(ADDRESS=
(PROTOCOL=TCP)
(HOST=bizim_server_name_veya_ip)
(PORT=1521)
)
(CONNECT_DATA=
(SERVER=dedicated)
(SID=BIZIM_SID)
)
)


Burada anlattıklarıma temel olan oracle versiyonları 10g ve 11g.
Ayrıca ASMM(Automatic Shared Memory Management 10g) veya
AMM(AutomaticMemory Managemet 11g) özelliklerinin aktif olduğunu varsaydım.
Bu varsayımımım yanlışsa, large_pool değerinin 50 mb civarı olarak, shared server konfigurasyonundan önce
ayarlanması gereklidir.Bu değer de duruma göre arttırılabilir.

Daha eski versiyonlar için farklı database configurasyonu gerekli olabilir.

Daha fazla bilgi için aşağıdaki bağlantılar da incelenebilir.

http://barisakverdi.blogspot.com/2010/10/oracle-shared-server-opsiyonu.html
http://barisakverdi.blogspot.com/2010/10/oracle-shared-server-konfigurasyonu.html
http://download.oracle.com/docs/cd/B28359_01/server.111/b28310/manproc001.htm
http://download.oracle.com/docs/cd/B10500_01/network.920/a96580/connect.htm
http://download.oracle.com/docs/cd/B10500_01/network.920/a96580/mts.htm
http://www.dba-oracle.com/t_mts_multithreaded_servers_shared.htm

Kaynak: http://barisakverdi.blogspot.com/search/label/Centura
Share:

Bir tablo üzerinde kayıt varsa güncelleme yoksa ekleme yapmak

Oracle’da merge kelimesini kullanarak tek sql ile kayıt varsa güncelleme yoksa ekleme yaptırabiliriz (Upsert).
Upsert Sql’imiz:
 merge into tablo t
 using dual s on (t.alan1=1)
 when matched then
   update set alan2='UPDATE'
 when not matched then
   insert (alan1,alan2) values (1,'INSERT');
Test ediyoruz :

SQL> create table tablo (alan1 number(10),alan2 varchar2(10));

Table created
SQL> select * from tablo;
      ALAN1 ALAN2
----------- ----------

SQL> merge into tablo t
2 using dual s on (t.alan1=1)
3 when matched then
4 update set alan2='UPDATE'
5 when not matched then
6 insert (alan1,alan2) values (1,'INSERT');

Done
SQL> select * from tablo;
      ALAN1 ALAN2
----------- ----------
          1 INSERT

SQL> merge into tablo t
2 using dual s on (t.alan1=1)
3 when matched then
4 update set alan2='UPDATE'
5 when not matched then
6 insert (alan1,alan2) values (1,'INSERT');

Done
SQL> select * from tablo;
      ALAN1 ALAN2
----------- ----------
          1 UPDATE

SQL> commit;
Commit complete
SQL>
Share:

Oracle’da sql ile bakiye hesaplama

Oracle’da analitik fonksiyonları kullanarak bakiye hesaplanabilmektedir. Örneğimizde bakiye test tablosu oluşturup test verilerini giriyoruz. Hesaplama sutunu için SUM grup fonksiyonunu OVER ile kullanarak satır satır çalışmasını sağlıyoruz. ORDER BY ile toplama işlemini hangi sırayla yapılmasını gerektiğini belirtiyoruz.

create table bakiye_test (
  id number primary key,
  tarih date not null,
  giren number not null,
  cikan number not null
);


insert into bakiye_test values (1,'05.04.2010',100,0);
insert into bakiye_test values (2,'07.04.2010',0,200);
insert into bakiye_test values (3,'09.04.2010',300,0);
insert into bakiye_test values (4,'10.04.2010',100,0);
insert into bakiye_test values (5,'12.04.2010',0,50);
insert into bakiye_test values (6,'19.04.2010',50,0);
insert into bakiye_test values (7,'21.04.2010',0,30);
commit;


SQL> SELECT B.*, SUM( GIREN-CIKAN ) OVER (ORDER BY TARIH ASC ) BAKIYE FROM BAKIYE_TEST B;

        ID TARIH            GIREN      CIKAN     BAKIYE
---------- ----------- ---------- ---------- ----------
         1 05.04.2010         100          0        100
         2 07.04.2010           0        200       -100
         3 09.04.2010         300          0        200
         4 10.04.2010         100          0        300
         5 12.04.2010           0         50        250
         6 19.04.2010          50          0        300
         7 21.04.2010           0         30        270

7 rows selected
Share:

13 Aralık 2010 Pazartesi

Length Fonksiyonu

LENGTH (string) fonksiyonu paremetre olarak verilen string‘in karakter uzunluğunu döndürür.Parametre olarak verilen değer null ise dönen değerde null olur. string ” (boş string) ise null olarak işlem görür. Uzunluk değeri Sıfır (0) olarak dönmez.
SQL> select Length('Zeki Güven') from dual;
LENGTH('ZEKIGüVEN')
-------------------
10
SQL> select Length(10) from dual;
LENGTH(10)
----------
2
SQL> select Length(sysdate) from dual;
LENGTH(SYSDATE)
---------------
10
SQL> select Length(null) from dual;
LENGTH(NULL)
------------
SQL> select Length('') from dual;
LENGTH('')
----------
SQL> Select nvl('','NULL ise çalışır') from dual;
NVL('','NULLISEÇALIŞIR')
--------------------------------
NULL ise çalışır
SQL> select Length('X') from dual;
LENGTH('X')
-----------
1”
veya Null değerinin uzunluğu sıfır değildir.


www.zekiguven.com 'a güzel yazısı için teşekkürler.

Share:

İki tarih arası farkı Yıl, Ay, Gün olarak bulmak

İki tarih arasında geçen zamanı bulmanız, yaş hesaplamanız gerekebilir. Oracle’da iki tarih
arasındaki farkı yıl, ay,gun olarak veren fonksiyon bulunmamaktadır.
Ben aşağıdaki şekilde bir sql ile hallettim:

SQL>SELECT
DOG_TAR DOGUM_TARIHI,
TRUNC( MONTHS_BETWEEN( SYSDATE, dog_tar)/12) yil,
TRUNC( MOD( MONTHS_BETWEEN( SYSDATE, dog_tar),12) ) ay,
TRUNC( (MONTHS_BETWEEN(SYSDATE,dog_tar)- TRUNC(MONTHS_BETWEEN( SYSDATE,
dog_tar))) /0.032258064516129) gun
FROM
PERSONEL;
DOGUM_TARIHI YIL AY GUN
------------ ---------- ---------- ----------
11.04.1970 39 9 24
01.01.1960 50 1 3
01.01.1998 12 1 3
04.08.1997 12 6 0
13.02.1982 27 11 22
0.032258064516129 iki gün arasındaki fark.
SQL>SELECT MONTHS_BETWEEN( SYSDATE,SYSDATE-1) FROM DUAL;
MONTHS_BETWEEN(SYSDATE,SYSDATE
------------------------------
0,032258064516129
Share:

6 Aralık 2010 Pazartesi

ORA-12549 Çözümü Mevcut!

Merhabalar,
Çok sıklıkla gerçekleşmese de, kısmen büyük çaptaki veritabanların başına gelebilen bir hatadır ORA-12549 hatası.
Veritabanına bağlanmak istediğiniz zaman ise şu şekilde hatalar alabilirsiniz;

ORA-12549: TNS: operating system resource quota exceeded
TNS-12518: TNS:listener could not hand off client connection
Ve veritabanına bağlanmanız reddedilir. İlk bakışta sıradan bir Oracle hatası ya da TNS hatası gibi gözüksede aslında bu bir İşletim sistemi kernel parametresi hatasından kaynaklanmaktadır.
Unix tabanlı işletim sistemlerinde bildiğiniz üzere belirli bir dökümantasyona göre Oracle kurulumları gerçekleştirilir, gerçekleştirilmesi tavsiye edilir. Gerçekleştirilmediği durumlarda ise, bir takım eksikliklerle Oracle veritabanı kurulacaktır ve ileride bir zaman karşınıza hata çıkma ihtimali olacaktır. Bu tarz işletim sistemlerinde kernel parametreleri vardır ve bağlı olan kullanıcılar ile ilgili işletim sistemi bazında bilgiler ve tanımlamaları içerir. Bu tanımlamalar belirli sayılarla temsil edilebilir.
Kernel parametrelerinin arasında "maxuproc" isimli bir parametre vardır. Default olarak 256 olarak belirlenir. Bu parametre her bir kullanıcı için azami işlem sayısını belirler. Oracle işletim sisteminden işlem tüketmek istediği zaman bu sayı sürekli artar ve 256'ya dayandığı zaman sisteme bağlantı dahil, veritabanı girişleri de sonlanabilir. Oracle'ın kurulum dökümantasyonlarında bu kernel parametrelerinin tavsiye edilen sayılarını görebilmek mevcut.
Bu parametreyi değiştirebilmek için root kullanıcısı ile bağlanmak şart. root ile bağlandıktan sonra "sam" yazarak parametremizi ayarlayacağımız Unix programına giriyoruz. Ardından "k" tuşuna basarak kernel parametrelerinin ayarlanması işlemine başlıyoruz. "Tunables" başlığının altında bir dizi parametre göreceksiniz. Burada "maxuproc" parametresini görebilirsiniz. Ayarlama olaraksa "(nproc*9)/10" yazarsanız, toplam nproc (işlem sayısı) sayısının %90'ını alabilir kullanıcılar demiş olursunuz. Bu sayede Oracle kullanıcınız daha fazla işlem tüketebilecek ve işlem sınırlamasından dolayı veritabanınız geçici süre kullanım dışı kalmayacaktır.
Unix/Linux işletim sistemlerine kurulum yaparken eğer kernel parametrelerinin kontrolünü atlarsanız kurulum aşamasında sorunlarla karşılaşmayabilirsiniz ancak ileride oluşabilecek sorunları da kabul etmiş olursunuz. Proaktif bir veritabanı yöneticisi olmak istiyorsanız ve sonradan başınızın ağrımasını istemiyorsanız unix tabanlı işletim sistemlerine Oracle veritabanı kurulumu yaparken mutlaka, mutlaka kernel parametrelerini kontrol edin!
maxuproc ile ilgili olarak google'da bir takım kısa çözümler mevcut. Örneğin;
Action: Acquire more operating system resource, or perform a different function.
Çok kısa ve anlaşılmayan bir çözüm değil mi? Daha fazla işletim sistemi kaynağı ayırmak ya da başka bir fonksiyon uygulamak ne demektir? Yukarıda yazdıklarımın çok fazla özeti olarak düşünüyorum ve maxuproc'u değiştirin diyorum :)
İyi akşamlar,
Share:

Blog Arşivi