Bu hatayı, insert işlemi yaptığım bir prosedürü serileştirmeye çalıştığım zaman aldım. Amacım, prosedürün farklı sessionlarda birbirini ezmeden çalıştırılabilmesiydi. Bunun için prosedürün tanım kısmına Serialization tanımını (SET TRANSACTION ISOLATION LEVEL SERIALIZABLE)
ekledim. Bu eklemeden sonra, prosedürü tek sessionda çalıştırsam bile hata vermeye başladı. Kısa bir aramadan sonra, ORACLE'da tabloların varsayılan olarak "Tablo seviyesinde" kilitlendiğini öğrendim. Bunu satır seviyesi olarak ayarlamak için, tabloyu oluştururken ROWDEPENDENCIES keywordunu eklemek gerekiyor. Örnek Table Create ve SP scripti aşağıdaki gibidir:
CREATE TABLE ALIBUDAK.TABLO_TEST
(
SID NUMBER,
NAME VARCHAR2(20)
)
ROWDEPENDENCIES
---------------------------------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE SP_TEST
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
DELETE FROM ALIBUDAK.TABLO_TEST;
INSERT INTO ALIBUDAK.TABLO_TEST
VALUES (1 ,'Ali');
COMMIT;
END;
22 Ocak 2014 Çarşamba
14 Ocak 2014 Salı
must declare the scalar @... problemi
Gridview datasource'unun DELETE COMMAND'ını yazınca karşıma bu problem çıktı. Problemin sebebi, Delete komutunda yazdığım;
DELETE FROM tablo WHERE id=@id
kısmındaki @id yi parametre olarak görememesi. Çözüm olarak gridview özelliklerinden "DataKeyNames" özelliğine değer olarak "id" yazdım. DataKeyNames'in değeri, tablodaki birincil anahtardır.
DELETE FROM tablo WHERE id=@id
kısmındaki @id yi parametre olarak görememesi. Çözüm olarak gridview özelliklerinden "DataKeyNames" özelliğine değer olarak "id" yazdım. DataKeyNames'in değeri, tablodaki birincil anahtardır.
windows mavi ekran problemlerinden 0×0000007b
STOP : 0×0000007b kodu ile karşınıza mavi ekran gelip bilgisayar sürekli yeniden başlayıp duruyorsa, BIOS'tan HDD'nizin sata denetiminin pasif (disabled) durumda olup olmadığı kontrol edilmeli.
Invalid postback or callback argument.
GridView Update işlemini yapmaya çalışırken karşıma çıkan hata:
Invalid postback or callback argument. Event validation is enabled using in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Çözüm için Page_Load() içine isPostBack şartının koyulması lazım.
Page_Load() {
if(!isPostBack){
//PAGE_LOAD İÇERİĞİNİ BU KOŞULUN ALTINA YAZMAK GEREKİYOR
}
}
Invalid postback or callback argument. Event validation is enabled using in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Çözüm için Page_Load() içine isPostBack şartının koyulması lazım.
Page_Load() {
if(!isPostBack){
//PAGE_LOAD İÇERİĞİNİ BU KOŞULUN ALTINA YAZMAK GEREKİYOR
}
}
Oracle WM_CONCAT Fonksiyonu
GRUPLAMAYI TEK SATIRDA NASIL YAPABİLİRİM?
Aynı kritere sahip değerleri tek satırda gruplamak için wm_concat fonksiyonunu kulanabiliriz.
Örnek üzerinden gidiyorum:
Tablo adı: CALISAN
Sütunlar: Maaş, İsim
Şimdi bu tabloya normal select çektiğimiz zaman karşımıza gelecek tablo 2 satırdan oluşuyor. İstediğimiz ise, tek satırda şunun gibi bir sonuç gelmesi:
MAAŞ İSİM
1000 Ali,Veli
Bunun için yazılacak sorgu şöyle olmalıdır:
SELECT MAAŞ, vm_concat(İSİM)
FROM CALISAN
GROUP BY MAAS
Aynı kritere sahip değerleri tek satırda gruplamak için wm_concat fonksiyonunu kulanabiliriz.
Örnek üzerinden gidiyorum:
Tablo adı: CALISAN
Sütunlar: Maaş, İsim
| MAAŞ | İSİM |
| 1000 | Ali |
| 1000 | Veli |
Şimdi bu tabloya normal select çektiğimiz zaman karşımıza gelecek tablo 2 satırdan oluşuyor. İstediğimiz ise, tek satırda şunun gibi bir sonuç gelmesi:
MAAŞ İSİM
1000 Ali,Veli
Bunun için yazılacak sorgu şöyle olmalıdır:
SELECT MAAŞ, vm_concat(İSİM)
FROM CALISAN
GROUP BY MAAS
TRUCATE ve DELETE farkı
Birçok meraklı developer'ın, aralarındaki farkı en az bir kez sorguladığı bir mevzudur bu. DELETE FROM varken TRUNCATE nedir ki? Aralarındaki en büyük fark şu: DELETE bir DML (Data Manipulation : Veri İşleme) komutudur. DML komutları, "commit" edilmeden kabul görmeyip, rollback ile geri alınabilirler, haliyle rollback segmentlerini kullanırlar. TRUNCATE ise bir DDL (Data Definition : Veri Tanımlama) komutudur. DDL komutları commit veya rollback ile değiştirilemezler. İşin özüne gelirsek: Bir tablo düşünün, 10 milyon satır ve 150 sütundan oluşan bir devanası. Bu tabloyu boşaltmak isterseniz, ve bunu DELETE ile yaparsanız, tüm veri rollback segmentlere yazılır, ki bu performans ve hız açısından hiç de istemediğimiz sonuçları beraberinde getirir. Bu yüzden tablonun tamamının boşaltılması istenen durumlarda TRUNCATE'in kullanılması önemlidir.
Oracle Trigger
Trigger'lar bir nevi programlamadaki Event Listener'lar gibidir. Örnek verelim: TABLO1 adında bir tablomuz var ve bu tablonun satırları üzerinde yapılan değişiklikleri (Update işlemlerini) loglamak istiyoruz. Bunun için bir Update trigger yazıp değişen veriyi, eski halini, hangi tarihte değiştiğini kendi belirlediğimiz bir tabloya insert edebiliriz.
Tablomuzu oluşturalım:
CREATE TABLE TABLO1
(user_id int, department_code int)
-------
Log tablomuzu oluşturalım
CREATE TABLE AUDIT_TABLO1
(user_id int, old_department_code int, new_department_code int, entry_date date)
-------
Tablolarımızı oluşturduktan sonra gelelim Trigger'a:
CREATE TRIGGER trg_tablo1
AFTER UPDATE
ON Tablo1
FOR EACH ROW
INSERT INTO AUDIT_TABLO1
(user_id, old_department_code, new_department_code, entry_date)
VALUES
(:new.user_id, :old.department_code, :new.department_code, sysdate)
Bu trigger ile log tablomuzda hem önceki hem update işleminden sonraki departman kodunu tutabiliriz. Bu şekilde hatalı update edilmiş kayıtların geri dönüşü için kolay bi fırsat yaratmış oluruz. ;)
Tablomuzu oluşturalım:
CREATE TABLE TABLO1
(user_id int, department_code int)
-------
Log tablomuzu oluşturalım
CREATE TABLE AUDIT_TABLO1
(user_id int, old_department_code int, new_department_code int, entry_date date)
-------
Tablolarımızı oluşturduktan sonra gelelim Trigger'a:
CREATE TRIGGER trg_tablo1
AFTER UPDATE
ON Tablo1
FOR EACH ROW
INSERT INTO AUDIT_TABLO1
(user_id, old_department_code, new_department_code, entry_date)
VALUES
(:new.user_id, :old.department_code, :new.department_code, sysdate)
Bu trigger ile log tablomuzda hem önceki hem update işleminden sonraki departman kodunu tutabiliriz. Bu şekilde hatalı update edilmiş kayıtların geri dönüşü için kolay bi fırsat yaratmış oluruz. ;)
'RSClientController' is undefined hatası
ReportViewer ile rapor görüntüleme aşamasında karşıma çıkan bu hatanın çözümünü şöyle buldum:
- IIS'te ilgili web sitesini bul. 'Handler Mappings' e gir.
- 'Add Managed Handler' a tıkla.
- Request path: Reserved.ReportViewerWebControl.axd
- Type: Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
- Name: Reserved.ReportViewerWebControl.axd
Ekleme işlemini yaptıktan sonra görüntülemede bir problem kalmadı.
- IIS'te ilgili web sitesini bul. 'Handler Mappings' e gir.
- 'Add Managed Handler' a tıkla.
- Request path: Reserved.ReportViewerWebControl.axd
- Type: Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
- Name: Reserved.ReportViewerWebControl.axd
Ekleme işlemini yaptıktan sonra görüntülemede bir problem kalmadı.
Reporting Services için bazı tarih ifade örnekleri
Yılın ilk günü:
DateSerial(YEAR(Today()),1,1)
n yıl sonranın ilk günü:
DateSerial(YEAR(Today())+n,1,1)
Ayın ilk günü:
DateAdd("d",1-DatePart("d",Today()),Today())
Ayın son günü:
DateAdd("d", -1.0 * DatePart("d", Today().AddMonths(1)), Today().AddMonths(1))
B ir önceki ayı son günü:
DateAdd("d", -1.0 * DatePart("d", Today()), Today())
DateSerial(YEAR(Today()),1,1)
n yıl sonranın ilk günü:
DateSerial(YEAR(Today())+n,1,1)
Ayın ilk günü:
DateAdd("d",1-DatePart("d",Today()),Today())
Ayın son günü:
DateAdd("d", -1.0 * DatePart("d", Today().AddMonths(1)), Today().AddMonths(1))
B ir önceki ayı son günü:
DateAdd("d", -1.0 * DatePart("d", Today()), Today())
Oracle nesnelerinin, ve içeriklerinin tanım tabloları
Örnek:
Elimizde, farklı durumlara göre yüklü miktarda işlem yapılması gereken bir veri yığını var. Kalem kağıt olsa, dip yekün alıp bir yere not alarak bu rakam üzerinden işleme devam etmek için sonucu muhafaza etmek isteriz. İşte geçici tablolar da tam bu işe yarıyor.Ham veriyi işleyip gerekli düzene soktuktan sonra, verinin bu halini geçici tablolara kaydederiz. Peki normal bir tablo create edip oraya kaydetsek olmaz mı? Olur, ama birden fazla kullanıcının aynı anda, aynı ham veriye ulaşıp aynı şekilde bir rapor hazırlamaya çalıştığını düşünelim. Bu işi yapmaya çalışan her kullanıcı için üretilen ara tablo, işlenmiş verilerle yeniden doldurulmaya çalışılacaktır. Bu işlem yeteri sıklıkta yapılırsa tablo bir türlü dolamayacağı için kimse rapora ulaşamayacaktır. Geçici tablolar veri kümelerinin, her Session için, hiçbirinin diğer session'larda oluşturulan verilere ulaşamayacağı ve ayrı ayrı hepsinin de aynı tablo ismi ile verileri muhafaza edileceği şekilde saklanmasına olanak sağlar. Yani A şahsı ham veriyi işleyip, sadece X session'ına özel TEMP_TABLE'da, B şahsı da aynı şekilde Y session'ına özel TEMP_TABLE'da hem de bu işlemleri aynı anda yaparak saklayabilir.
Geçici tabloların normal tablolardan Syntax olarak çok da farkı yok.
CREATE GLOBAL TEMPORARY TABLE TEMP_TABLE1
(
ID NUMBER,
ENTRY_DATE DATE
)
ON COMMIT PRESERVE ROWS;
Burada, PRESERVE ROWS, geçici tablodaki verilerin Session sonlanana kadar tabloda barındırılacağını, Session sonunda ise tablodan silineceğini belirtir. Session değil de Commit işlemi bazında bu işlemin olması için DELETE ROWS yazmak yeterlidir.
Elimizde, farklı durumlara göre yüklü miktarda işlem yapılması gereken bir veri yığını var. Kalem kağıt olsa, dip yekün alıp bir yere not alarak bu rakam üzerinden işleme devam etmek için sonucu muhafaza etmek isteriz. İşte geçici tablolar da tam bu işe yarıyor.Ham veriyi işleyip gerekli düzene soktuktan sonra, verinin bu halini geçici tablolara kaydederiz. Peki normal bir tablo create edip oraya kaydetsek olmaz mı? Olur, ama birden fazla kullanıcının aynı anda, aynı ham veriye ulaşıp aynı şekilde bir rapor hazırlamaya çalıştığını düşünelim. Bu işi yapmaya çalışan her kullanıcı için üretilen ara tablo, işlenmiş verilerle yeniden doldurulmaya çalışılacaktır. Bu işlem yeteri sıklıkta yapılırsa tablo bir türlü dolamayacağı için kimse rapora ulaşamayacaktır. Geçici tablolar veri kümelerinin, her Session için, hiçbirinin diğer session'larda oluşturulan verilere ulaşamayacağı ve ayrı ayrı hepsinin de aynı tablo ismi ile verileri muhafaza edileceği şekilde saklanmasına olanak sağlar. Yani A şahsı ham veriyi işleyip, sadece X session'ına özel TEMP_TABLE'da, B şahsı da aynı şekilde Y session'ına özel TEMP_TABLE'da hem de bu işlemleri aynı anda yaparak saklayabilir.
Geçici tabloların normal tablolardan Syntax olarak çok da farkı yok.
CREATE GLOBAL TEMPORARY TABLE TEMP_TABLE1
(
ID NUMBER,
ENTRY_DATE DATE
)
ON COMMIT PRESERVE ROWS;
Burada, PRESERVE ROWS, geçici tablodaki verilerin Session sonlanana kadar tabloda barındırılacağını, Session sonunda ise tablodan silineceğini belirtir. Session değil de Commit işlemi bazında bu işlemin olması için DELETE ROWS yazmak yeterlidir.
Oracle JOIN ile UPDATE işlemi
Bir tabloda Update etmek istediğimiz alanın değerinin başka bir tablodan gelmesi gerekiyorsa, bunu alt sorgularla yapıyoruz.
update tablo1
set son_guncelleme_tarihi =
(
select max(guncelleme_tarihi)
from tablo2 where tablo1.kayit_no=tablo2.kayit_no
)
Peki birden çok alanın update edilmesi gerektiği durumlarda ne yapacağız? Her biri için birer alt sorgu yazmak yerine MERGE kullanımı daha yerinde olacaktır.
MERGE INTO TABLO1 T1
USING
(
SELECT
TAB1.ROWID AS RID,
TAB2.GUNCELLENECEK_SUTUN1 AS GUNC1,
TAB2.GUNCELLENECEK_SUTUN2 AS GUNC2,
TAB2.GUNCELLENECEK_SUTUNX AS GUNCX
FROM TABLO2 TAB2, TABLO1 TAB1
WHERE TAB1.PK_SUTUN=TAB2.PK_SUTUN
) T2
ON(T1.ROWID=T2.RID)
WHEN MATCHED THEN UPDATE
SET
T1.GUNCELLENECEK_SUTUN1=T2.GUNC1,
T1.GUNCELLENECEK_SUTUN2=T2.GUNC2,
T1.GUNCELLENECEK_SUTUNX=T2.GUNCX
update tablo1
set son_guncelleme_tarihi =
(
select max(guncelleme_tarihi)
from tablo2 where tablo1.kayit_no=tablo2.kayit_no
)
Peki birden çok alanın update edilmesi gerektiği durumlarda ne yapacağız? Her biri için birer alt sorgu yazmak yerine MERGE kullanımı daha yerinde olacaktır.
MERGE INTO TABLO1 T1
USING
(
SELECT
TAB1.ROWID AS RID,
TAB2.GUNCELLENECEK_SUTUN1 AS GUNC1,
TAB2.GUNCELLENECEK_SUTUN2 AS GUNC2,
TAB2.GUNCELLENECEK_SUTUNX AS GUNCX
FROM TABLO2 TAB2, TABLO1 TAB1
WHERE TAB1.PK_SUTUN=TAB2.PK_SUTUN
) T2
ON(T1.ROWID=T2.RID)
WHEN MATCHED THEN UPDATE
SET
T1.GUNCELLENECEK_SUTUN1=T2.GUNC1,
T1.GUNCELLENECEK_SUTUN2=T2.GUNC2,
T1.GUNCELLENECEK_SUTUNX=T2.GUNCX
Control.Visible ve css Display özelliklerinin Javascript üzerindeki etkisi
Kendi oluşturduğum bir CreditCard.ascx kontrolü içindeki form elemanlarına girilen verilerin validasyonlarını kendi içinde Javascript kullanarak yapıyorum. Bu kontrolü herhangi bir aspx sayfasına ekleyip, visible özelliğiini false yapınca, içeriğindeki Javascriptin yüklenmediğini gördüm. Problemi gidermek için, kontrolün (veya içinde bulunduğu panel veya div'in) görünürlük ayarını, Visible özelliğini değil, CSS->Display özelliğini kullanarak yaptım. Bu şekilde Javascript, kontrol görünür olsa da olmasa da sayfaya yükleniyor.
divYeni.Style["display"] = "none"; // "none" görünmez "block" görünür.
divYeni.Style["display"] = "none"; // "none" görünmez "block" görünür.
XML formatında kaydedilmiş bir alanın içeriğine ulaşmak
TABLO1 isimli tablomuzda, PARAMETRELER isimli alanın içeriği XML formatında kayıtlı olsun.
SELECT parametreler FROM TABLO1
PARAMETRELER
XML örneğinde 2 adet parametre bulunmaktadır. Bu parametrelerin adları ve değerlerine ulaşmak için:
select
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=1]/@id'),0)aspar1_adi,
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=1]/@value'),0)aspar1_degeri,
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=2]/@id'),0)aspar2_adi,
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=2]/@value'),0)aspar2_degeri
from TABLO1
PAR1_ADI PAR1_DEGERI PAR2_ADI PAR2_DEGERI
OGR_KODU 055 TARIH 30/07/2012
SELECT parametreler FROM TABLO1
PARAMETRELER
XML örneğinde 2 adet parametre bulunmaktadır. Bu parametrelerin adları ve değerlerine ulaşmak için:
select
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=1]/@id'),0)aspar1_adi,
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=1]/@value'),0)aspar1_degeri,
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=2]/@id'),0)aspar2_adi,
substr(extract(xmltype(parametreler),'/parameters/parameter[position()=2]/@value'),0)aspar2_degeri
from TABLO1
PAR1_ADI PAR1_DEGERI PAR2_ADI PAR2_DEGERI
OGR_KODU 055 TARIH 30/07/2012
TOAD for Oracle DataGrid üzerinden Update
PL/SQL Developer'da select sorgusunun sonuna FOR UPDATE ekleyerek grid hücresi üzerinden Update etmek mümkünken, TOAD'da bunu denedim ve sonuç alamadım. Bu özelliğin TOAD'da olmaması beni hayal kırıklığına uğratmıştı ki, kurbağa karşıma bir sürprizle çıkageldi. TOAD'ta yazılan select sorgusuna ROWID eklenerek bu özelliği mümkün kılabiliyorsunuz. Şöyle ki:
SELECT COLUMN1, COLUMN2 FROM TABLE1
sorgusu, dönen grid üzerinden elle update'e izin vermezken,
SELECT COLUMN1, COLUMN2, ROWID FROM TABLE1
ile bu işlemi yapabiliyorsunuz. COMMIT etmeyi unutmayın.!.
SELECT COLUMN1, COLUMN2 FROM TABLE1
sorgusu, dönen grid üzerinden elle update'e izin vermezken,
SELECT COLUMN1, COLUMN2, ROWID FROM TABLE1
ile bu işlemi yapabiliyorsunuz. COMMIT etmeyi unutmayın.!.
Oracle fonksiyondan Tablo döndürme
Bir fonksiyondan
tablo döndürmek için, önce döndürülecek tablonun imza tipi (Sütun adları ve
tipleri) ve ilgili tipin tablo nesnesi tanımlanmalıdır.
create type alibudak.type_x is object(
ODEME_TIP_KODU NUMBER,
ACIKLAMA VARCHAR2(50)
);
create TYPE alibudak.table_x IS TABLE OF type_x;
Bu tipler
tanımlandıktan sonra fonksiyon PIPELINED keyword’ü ile tanımlanır. Ben örneği
Package’da yaptım.
CREATE OR REPLACE PACKAGE body ALIBUDAK.pkg_test AS
function odeme_tipleri_getir
return alibudak.table_x pipelined
is
kayitlar alibudak.table_x;
begin
for satir in (
select
payment_type,
description
from ankara.t001hasodt
where company_Code=2
)
loop
pipe row (type_x(satir.payment_type, satir.description));
end loop;
end;
end;
/
Tanımlamalar
tamamlandıktan sonra fonksiyon SQL bloğu
içerisinde TABLE olarak çağrılır ve işlem tamamlanmış olur. Çağrılan fonksiyon,
tıpkı tablo gibi davranır. Örneğin dönen sütunlara direkt olarak koşul (WHERE)
eklenebilir.
select
*
from table(alibudak.pkg_test.odeme_tipleri_getir()) t
where t.odeme_tip_kodu in(1,3,11)
Kaydol:
Kayıtlar (Atom)