FireBird'de ISNULL ile ilgili

Firebird ve Interbase veritabanları ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2247
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

FireBird'de ISNULL ile ilgili

Mesaj gönderen Kuri_YJ »

Merhaba Arkadaşlar aslında bu bilgiyi sizlerle paylaşmak istedim. Delphi Listesinde bir ara bir mail atmıştım, FireBird'de, MSSQL'deki ISNULL'a benzer veya karşılık bir fonksiyon var mı diye, ancak yanıt alamamıştım ve oturup kendim bir ISNULL UDF'i hazırlamıştım. ISNULL ile birlikte birkaç küçük fonksiyon daha hazırlamıştım. Ancak bugün FireBird'ün Release Notlarına göz atarken ISNULL'ın benzeri bir UDF olduğunu gördüm.

Ekte bulduğum yazının örneği var, FireBird v1.0 Release Notes'tan alıntı,
In the new Firebird UDF library, FBUDF.dll

Development by Claudio Valderrama C., funded by Craig L. Leonardi
Distributed with this release is FBUDF.dll, the first Firebird UDF library using BY DESCRIPTOR syntax to
pass arguments, which provides more versatility. In declaring the functions in SQL, notice the
differences between the multiple declarations that map to the same function.

See, for example, that
INULLIF() is mapped to by both INULLIF() and I64NULLIF().
Author Claudio Valderrama comments that the library is still in beta and warns that it will probably
exhibit some bugs. So far it has not been compiled on any other platform but Windows. Bug reports
and comments are welcome.

The source and the DDL for declarations are in the Firebird CVS tree. To find them, select 'Browse the
CVS tree' from http://sourceforge.net/projects/firebird, click on 'Browse CVS Repository' and then
select Developers | Latest sources | interbase | extlib | fbudf.*.
NVL() functions for both exact precision ('invl') and string ('snvl') parameters

These functions attempt to mimic the NVL function of Oracle, to output an actual value when
the column has a NULL value. They take two arguments, the first being the expression being
tested for NULL, the second the value to output if the first argument is NULL. NVL will return
the first argument if it's not null and the second argument if the first one is null. If both are
null, you get null.

The pair of parameters should be compatible, either two numeric values (smallint, int, int64)
or two string values (char, varchar, cstring). The engine does not honor the parameter types
when using the technique exercised by FBUDF, so mixing a numeric and a string as arguments
will yield wrong results.

NULLIF() for string ('snullif'), integer ('inullif') and INT64 ('i64nullif') parameters
NULLIF should take two arguments, returning NULL if they are equivalent, or the result of the
first expression if they are not equivalent. Because of a shortcoming in the engine which
prevents NULL being returned from a UDF, each of these three functions returns a zeroequivalent.

This non-standard behaviour makes it not useful for "casting" certain values as
NULL in order to have aggregate functions ignore nulls.
NOTE that the function call to both the integer and int64 functions is the same ('inullif').

Day-of-Week functions - one returning a short string ('SDOW'), the other a longer one ('DOW'), from a
timestamp input. The return strings can be localized.
Several functions to add segments of time to a timestamp - 'addDay', 'AddWeek', etc.

A RIGHT() function (like RString in BASIC) to return the rightmost n characters from an input string.
A GetExactTimestamp() function returning the system timestamp with milliseconds precision.

Truncate()and i64truncate() truncate 32-bit and 64-bit integers respectively, taking scaled (exactprecision)
numerics of any range (up to 9 in Dialect 1 or up to 19 in Dialect 3) and returning the wholenumber
portion. They do not work with float or double types.
Herkese kolay gelsin, bu fonksiyona ihtiyaç duyanlara da bir çeşit müjde :)
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7586
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Mesaj gönderen mussimsek »

bilgi için teşekkürler.

Kolay gelsin.
Kullanıcı avatarı
safak
Şafak EBESEK
Mesajlar: 165
Kayıt: 05 Ağu 2003 04:39
Konum: Istanbul
İletişim:

Mesaj gönderen safak »

WHERE field IS NULL
olarak çalışıyor.
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2247
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Mesaj gönderen Kuri_YJ »

Merhabalar,

safak arkadaşımıza yardım etmeye çalıştığı için teşekkür ederiz. Ancak bizim kasdettiğimiz ISNULL function'ı farklı bir amaç için kullanılmakta. Yani sadece where clause'unda kullanılmak üzere yapılmış bir function değil !...

Şöyle açıklayayım,

Bir table'da Null fieldlar olabilsin ve bu null fieldlar için matematiksel işlemler gerçekleştirelim.

Table

F1 F2 F3 F4
50 10 Null Null

İşlemimiz de şu şekilde olsun.

F4 := (F1 + F2) - F3 ;

Eğer yukarıdaki işleme Null değeri karışırsa ortaya çıkan sonuç Null olacaktır. Ancak biz F3 fieldı Null olursa 0 (Sıfır) kabul et diyerek formülü uygulamak istiyorsak, burada bir funtion'a ihtiyaç duyuluyor yada bir If Then Else bloğuna ihtiyaç duyuluyor.

F4 := (F1 + F2) - INULLIF(F3,0) ;

şeklinde yazarsak F4'ün sonucu 60 olur. Bizim kasdettiğimiz ISNULL kontrolu bu şekilde. Bilmem açıklayabildim mi!...

Ancak şunu da belirteyim ki yukarıdaki function'lar hernedense düzgün çalışmadı. Ben denemelerini yaptım ama sonuçta yine Null döndü. Zaten yazan kişinin notlarında BUG olabilir diyordu :) Demek ki bir şekilde benim elimdeki versiyonda bu BUG var. Daha derin inceleyip (yada takip edip yeni versiyonlarını bulmak gerekiyor).

Ancak isteyen olursa bizim yazdıklarımızı gönderebilirim.

Kolay gelsin.
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

sırası gelmişken bir ek de ben yapayım;

oracle da güzel bir fonksiyon var: DECODE()

decode(değişken, 1.değer, 1.dönecek_değer, 2.değer, 2.dönecek_değer, 3.değer, 3.dönecek_değer, ..., else_durumunda_dönecek_değer)

burada değişken, n.değer e eşitse n.dönecek_değer i alacak aksi halde else durumundaki değeri döndürür.

yani burada verdiğiniz fonksiyonlar biçiminde kullanmak da mümkün.

decode(alan, null, 0);

belki udf olarak da vardır.
Kullanıcı avatarı
safak
Şafak EBESEK
Mesajlar: 165
Kayıt: 05 Ağu 2003 04:39
Konum: Istanbul
İletişim:

NULL

Mesaj gönderen safak »

NULL için database değerlendirme tutumu SQL2 standartlarında açıkca belirtilmiş. Tabii sürümlere göre farklılık gösterebilir. Davranışlar NULL değerini gözardı etmek ya da içinde NULL barındıran işlemleri NULL olarak ifade etmek arasında salınıyor. Aslında NULL 'un ele alınışı biraz da tasarımcının sorumluluğunda. Tanımlanan tasarım ortamında NULL (Henüz değer atanmamış) ifadesi gerçekten 0 (sıfır) anlamına geliyorsa, bu durumda ilgili alanlara default olarak 0 atamak ya da 0 da olsa bir değer girmeye zorlamak, daha sonra ortaya çıkabilecek pek çok değerlendirme sorununu daha baştan çözebilir. Eğer tasarım kriterleri sonucunda kaçınılmaz olarak NULL atamak ve buna zaman zaman 0, zaman zaman atanmamış değerlendirmesi yapılmak istenirse, alternativ bir kolay hesaplama yolu olarak, sonuç kümesi üzerinde WHERE ile pass uygulanarak , problemin tanımına göre NULL alanlara hesaplama için gerekli değerler atanması ve sonra istenen sorgulamaların uygulanması yolu da göz önünde bulundurulabilir.

Tabii tasarımın yapısına göre Numerik alanlar dışında NULL atanmış alanların nasıl değerlendirilmesi gerketiği de ayrı bir yaklaşım gerektirebilir.

NULL 'u "henüz tanımlanmamıs" tanımına bağlı kalarak kullanmak bir çok sorunu baştan çözebiliyor. Alanlarda görülen NULL değerleri sadece "henüz değer atanmamış" anlamına gelmeli. Eğer mümküse nümerik alanlar için sıfır, karaker alanlar için bir boşluk (varsa diğer tipler için anlamlı bir değer) atamak kararsız yapıların oluşumunu engelliyor.
ilkeryesiloglu
Üye
Mesajlar: 18
Kayıt: 07 Haz 2004 09:04
Konum: Mersin
İletişim:

Mesaj gönderen ilkeryesiloglu »

Merhaba Arkadaşlar,
Benim de FireBird ve Delphi ile ilgili bir sorunum var.
Delphi içinde yazılmış bir SQL komutu içerisinde kullandığım bir parametreye değer atadığımda o değere göre sorgulamasını değer vermemiş isem o parametreyi dikkate almamasını istiyorum.
Örnek:
Bir tabloda ULKE adına varchar(3) tipinde ve PARABR adına varchar(3) tipinde iki saha var.

select * from HAREKET
where
PARABR=:S_PARABR
and
ULKE=:S_ULKE

bildiğiniz gibi delphi içinde S_PARABR ve S_ULKE parametrelerine değer atarken

aa.ParamByName('S_PARABR').asString:='USD';
aa.ParamByName('S_ULKE').asString:='ABD';

kullanılıyor. Parametrik kullanım ise tekrarlamalı sogularda PREPARE işlemi ardından iyi bir performans sağlıyor.

Benim öğrenmek istediğim ise;
aa.ParamByName('S_PARABR').asString:='USD';
aa.ParamByName('S_ULKE').clear;

veya sadece

aa.ParamByName('S_PARABR').asString:='USD';

dediğimde bana sadece PARABR=USD olan kayıtlar gelsin fakat ULKE yi dikkate almasın.

Yardımcı olabilecek arkadaşlarla bilgilerini paylaşmaktan çok memnun olurum.

İyi çalışmalar.
Kullanıcı avatarı
mege
Admin
Mesajlar: 2360
Kayıt: 05 Şub 2004 04:32
Konum: Beşiktaş
İletişim:

Mesaj gönderen mege »

sp kullanın, sp içinde if lerle kontrolleri yapıp gerekli sorguyu kurarsınız.
.-.-.-.-.-.-.-. ^_^
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Bu işin en kolay yolu geçirilen parametreye NULL atamaktır. Null atarken de .AsInteger veya .AsString yerine .AsVariant demek gerekir :!:

Kod: Tümünü seç

select * from HAREKET
where (:S_PARABR IS NULL OR PARABR = :S_PARABR)
  and (:S_ULKE IS NULL OR ULKE = :S_ULKE) 

Kod: Tümünü seç

if Seçilmişse then
  aa.ParamByName('S_PARABR').asString:='USD'
else
  aa.ParamByName('S_PARABR').AsVariant := NULL;
if Seçilmişse then
  aa.ParamByName('S_ULKE').asString:='ABD'
else
  aa.ParamByName('S_ULKE').AsVariant := NULL; 
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
Kullanıcı avatarı
kadirkurtoglu
Üye
Mesajlar: 748
Kayıt: 22 May 2005 01:20
Konum: Uzakta Görünen Tepeden...

Mesaj gönderen kadirkurtoglu »

merhabalar.
F4 := (F1 + F2) - INULLIF(F3,0) ;


matematiksel ifadelerde yapılabilirmi bilmiyorum ama. kayıtları seçerken böyle bir kontrolün yapılabildiğini duymuştum.

select (case when F1 is null then 0 else F1 end), F2, F3 .......

şeklinde... veya select coalesce(F1, 0), ....
Bir mum, yanındaki mumları tutuşturmakla,
ışığında hiç bir şey kaybetmez.

Mevlana

OS win.10, IDE Delphi 10.3, RDBMS Firebird and MSSQL, BROWSER Chrome
Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Mesaj gönderen Fatih! »

coalesce var

Kod: Tümünü seç

select
coalesce(ALIS,'0') as ALIS
   FROM
TBLHESAP
Buda hesaplanmış alan örnneği.
kullanımını çözene kkadar canım çıktı :::)

Kod: Tümünü seç

select
coalesce(ALIS+SATIS,ALIS,SATIS,'0') AS TOPLAM
   FROM
TBLHESAP
Detaylı Bilgi İçin Buraya Tıklayın
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Madem başlık tazelendi bilgilerimizi de tazeleyelim :wink:

http://www.ibexpert.info/firebird/docum ... ressions/b)%20%20COALESCE/18271.html
b) COALESCE

Allows a column value to be calculated by a number of expressions, from which the first expression to return a non-NULL value is returned as the output value.

Format

<case abbreviation> ::=
| COALESCE <left paren> <value expression> { <comma> <value expression> }... <right paren>



Syntax Rules

i) COALESCE (V1, V2) is equivalent to the following <case specification>:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END

ii) COALESCE (V1, V2,..., Vn), for n >= 3, is equivalent to the following:
<case specification>:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2,...,Vn) END

Examples

SELECT
PROJ_NAME AS Projectname,
COALESCE(e.FULL_NAME,'[> not assigned <]') AS
Employeename
FROM
PROJECT p
LEFT JOIN EMPLOYEE e ON (e.EMP_NO = p.TEAM_LEADER);

SELECT
COALESCE(Phone,MobilePhone,'Unknown') AS "Phonenumber"
FROM
Relations
Document-ID: 18271
28.04.2005
c) NULLIF

Returns NULL for a sub-expression if it has a specific value, otherwise returns the value of the sub-expression.



Format

<case abbreviation> ::=

NULLIF <left paren> <value expression> <comma> <value expression> <right paren>



Syntax Rules

NULLIF (V1, V2) is equivalent to the following <case specification>:

CASE WHEN V1 = V2 THEN NULL ELSE V1 END



Example



UPDATE PRODUCTS

SET STOCK = NULLIF(STOCK,0)
Document-ID: 18277
28.04.2005
http://www.ibexpert.info/firebird/docum ... 18057.html
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
Kullanıcı avatarı
kadirkurtoglu
Üye
Mesajlar: 748
Kayıt: 22 May 2005 01:20
Konum: Uzakta Görünen Tepeden...

Mesaj gönderen kadirkurtoglu »

yeniden merhaba
) COALESCE (V1, V2) is equivalent to the following <case specification>:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
ifadesindeki IS NOT NULL'u merak ettim. ben is null kullanıyorum. burdaki not olumsuzluk eki ''değilse'' manasında mı yoksa Not Null ''boş geçilemez''

anlamak istediğim ordaki not ifadesi not null fieldleri mi kapsıyor. ben öyle bir anlam çıkardım.
Bir mum, yanındaki mumları tutuşturmakla,
ışığında hiç bir şey kaybetmez.

Mevlana

OS win.10, IDE Delphi 10.3, RDBMS Firebird and MSSQL, BROWSER Chrome
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Kod: Tümünü seç

CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
Buradaki NOT NULL V1 in null olmama durumu demek :wink: Yani null değilse kendi değeri dönsün null ise V2 nin değeri dönsün.
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
Kullanıcı avatarı
kadirkurtoglu
Üye
Mesajlar: 748
Kayıt: 22 May 2005 01:20
Konum: Uzakta Görünen Tepeden...

Mesaj gönderen kadirkurtoglu »

+ olarak ilginç bir durum oldu. sp yi IBexpertte çalıştırıp denediğim de nul alanları 0 yapıyor. Delphi tarafında kod ile çalıştırdığım da. sonuç doğru dönüyor ancak null alanlar null geliyor.
Bir mum, yanındaki mumları tutuşturmakla,
ışığında hiç bir şey kaybetmez.

Mevlana

OS win.10, IDE Delphi 10.3, RDBMS Firebird and MSSQL, BROWSER Chrome
Cevapla