Discussion:
Zamiana NULL na String
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
Toma
2004-07-26 13:08:17 UTC
Permalink
Witam,
mam problemik z Interbasem i odczytem NULLowej wartosci z Query. W jaki
sposob moge zamienic ja na string? Fieldbyname('nazwa').asstring nie
dziala... caly czas wyskakuje mi blad Could not convert... NULL into String,

Jakies pomysly?

Oczywiscie chce zamienic NULL na pusty string.


Pozdr
Toma
Piotr Brzeziñski
2004-07-26 13:35:07 UTC
Permalink
Post by Toma
mam problemik z Interbasem i odczytem NULLowej wartosci z Query. W jaki
sposob moge zamienic ja na string? Fieldbyname('nazwa').asstring nie
Witam!

VarToStr(FieldByName('nazwa').AsVariant);

Piotr Brzeziński
szaman
2004-07-26 14:02:37 UTC
Permalink
Post by Piotr Brzeziñski
VarToStr(FieldByName('nazwa').AsVariant);
Serio ten Interbase taki porypany, że null nie daje pustego stringa ?!
A tak go zachwalają?!

Co do pytacza i jego pytania oraz zamiany null->string to w miejscach
krytycznych dla wydajności odradzałbym zamienianie na "warianta",
przecież sa inne sposoby.
--
Szukam pracy.
Yahoo! Messenger: tomek_cwajda
GG : 915593
{67B14976-ABB4-4A3B-869B-84B5CCA1F569}
miab
2004-07-26 14:30:51 UTC
Permalink
Post by szaman
Post by Piotr Brzeziñski
VarToStr(FieldByName('nazwa').AsVariant);
Serio ten Interbase taki porypany, że null nie daje pustego stringa ?!
A tak go zachwalają?!
A co to za dziadowstowo co to zamiast null'a daje pustego stringa?
Null jest null w porządnych implementacjach zaś pustyn string
pusty string.

miab
Morff
2004-07-26 21:04:29 UTC
Permalink
Post by miab
A co to za dziadowstowo co to zamiast null'a daje pustego stringa?
Null jest null w porządnych implementacjach zaś pustyn string
pusty string.
a oracle na ten przykład ...

pozdro
Morff
miab
2004-07-26 23:24:30 UTC
Permalink
Post by Morff
Post by miab
A co to za dziadowstowo co to zamiast null'a daje pustego stringa?
Null jest null w porządnych implementacjach zaś pustyn string
pusty string.
a oracle na ten przykład ...
Co Oracle na ten przykład?
Podejrzewam że to samo:
<cy>
Wartości puste

Pola tabeli mogą przyjmować wartości puste, pod warunkiem, że nie zostało to
zabronione przez projektanta bazy danych. Wartość pusta (NULL) nie jest
równa wartości 0 i w wyniku obliczenia dowolnego wyrażenia, którego
argumentem jest NULL otrzymuje się również wartość pustą (NULL).

Funkcja NVL pozwala dokonać konwersji wartości aktualnej (do niej samej) lub
wartości pustej do wartości domyślnej. Działanie funkcji NVL ilustruje
przykład:

NVL(COMM, 0) zwróci wartość COMM, jesli nie jest to wartość pusta lub 0
jeśli COMM ma wartość NULL.

Większość funkcji grupujących ignoruje wartość NULL. Np. zapytanie, którego
zadaniem jest obliczenie średniej z pięciu następujących wartości: 1000,
NULL, NULL, NULL i 2000 zwróci 1500 ponieważ (1000 + 2000)/2 = 1500.

Jedyne operatory porównania, które można użyć do wartości pustej to IS NULL
i IS NOT NULL. Jeśli zostanie użyty jakikolwiek inny operator porównania do
wartości pustej, to wynik jest nieokreślony. Ponieważ NULL reprezentuje brak
wartości, więc nie może on być równy ani nierówny jakiejkolwiek innej
wartości, również innemu NULL.

ORACLE traktuje warunki, których wynik jest nieznany jako fałszywe. Tak więc
warunek COMM = NULL jest nieznany, w związku z czym rozkaz SELECT z takim
warunkiem nie zwróci nigdy żadnego wiersza. Jednak w takiej sytuacji ORACLE
nie zgłosi informacji o wystąpieniu błędu.
</cy>
http://galaxy.uci.agh.edu.pl/~chwastek/lectures/db/dbnull.html

A co do rozwiązania problemu z InterBase to możan użyć fbudf.dll z
FireBird1/1.5
który ma podobne funkcje co Oracle:
<cy>
--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
declare external function invl
int by descriptor, int by descriptor
returns int by descriptor
entry_point 'idNvl' module_name 'fbudf';

--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
declare external function i64nvl
numeric(18,0) by descriptor, numeric(18,0) by descriptor
returns numeric(18,0) by descriptor
entry_point 'idNvl' module_name 'fbudf';

--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
declare external function dnvl
double precision by descriptor, double precision by descriptor
returns double precision by descriptor
entry_point 'idNvl' module_name 'fbudf';

--FBUDF_API paramdsc* sNvl(paramdsc* v, paramdsc* v2, paramdsc* rc)
declare external function snvl
varchar(100) by descriptor, varchar(100) by descriptor,
varchar(100) by descriptor returns parameter 3
entry_point 'sNvl' module_name 'fbudf';

--FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
declare external function inullif
int by descriptor, int by descriptor
returns int by descriptor
entry_point 'iNullIf' module_name 'fbudf';

--FBUDF_API paramdsc* dNullIf(paramdsc* v, paramdsc* v2)
declare external function dnullif
double precision by descriptor, double precision by descriptor
returns double precision by descriptor
entry_point 'dNullIf' module_name 'fbudf';

--FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
declare external function i64nullif
numeric(18,4) by descriptor, numeric(18,4) by descriptor
returns numeric(18,4) by descriptor
entry_point 'iNullIf' module_name 'fbudf';

--FBUDF_API paramdsc* sNullIf(paramdsc* v, paramdsc* v2, paramdsc* rc)
declare external function snullif
varchar(100) by descriptor, varchar(100) by descriptor,
varchar(100) by descriptor returns parameter 3
entry_point 'sNullIf' module_name 'fbudf';
</cy>

Które w FireBird1.5.x.yyyy są niepotrzebne ale zachowano dla
kompatybilności:

<cy>
The *NVL and *NULLIF functions remain for backward compatibility, but are
deprecated by the introduction of the new internal functions CASE, COALESCE
and NULLIF.
</cy>
http://www.ibexpert.info/firebird/documentation/Firebird%20Release%20Notes%20v1.5/External%20Functions%20(UDFs)/In%20fbudf/18507.html

miab
Morff
2004-07-27 06:00:24 UTC
Permalink
Post by miab
Post by Morff
Post by miab
A co to za dziadowstowo co to zamiast null'a daje pustego stringa?
a oracle na ten przykład ...
Do wersji 8.x
Post by miab
Pola tabeli mogą przyjmować wartości puste, pod warunkiem, że nie zostało to
zabronione przez projektanta bazy danych. Wartość pusta (NULL) nie jest
równa wartości 0 i w wyniku obliczenia dowolnego wyrażenia, którego
argumentem jest NULL otrzymuje się również wartość pustą (NULL).
to dotyczy wartości numerycznych z tego co widze , a nie stringów więc to
nie jest dobry przykład
Post by miab
Funkcja NVL pozwala dokonać konwersji wartości aktualnej (do niej samej) lub
wartości pustej do wartości domyślnej. Działanie funkcji NVL ilustruje
NVL(COMM, 0) zwróci wartość COMM, jesli nie jest to wartość pusta lub 0
jeśli COMM ma wartość NULL.
przykład :
select nvl('',0) from dual
wynik = 0

Pozdrawiam
Morff
szaman
2004-07-27 09:23:43 UTC
Permalink
Post by miab
Post by szaman
Post by Piotr Brzeziñski
VarToStr(FieldByName('nazwa').AsVariant);
Serio ten Interbase taki porypany, że null nie daje pustego stringa ?!
A tak go zachwalają?!
A co to za dziadowstowo co to zamiast null'a daje pustego stringa?
Null jest null w porządnych implementacjach zaś pustyn string
pusty string.
OOOhohohho ;-)
Cholera znowu nie obeszłem tej świętej krowy a chyba nadepłem (jak by
powiedział Kiepski a przed nim to nasz ulubiony prezydent).
Dobrze wiem jak ważna jest wartośc null i różni się od pustego stringa
i mało tego wiem, że ty wiesz, że ja wiem :-)
Poza tym wiem, ze intebase wypełnia standardy więc i nulle ma jak sie
należy - ale tu raczej jest kwestia delphi oraz komponentów które
powinny zwracać pustego stringa jeżeli chcą wypełniać standardy
delphio'wych komponentów. Wyobraź sobie teraz dbgrida podłączonego do
do query które zwraca również nulle albo inny kod programu napisany
juz z tym założeniem że null to pusty string - oczywiście taki program
leży i kwiczy.
O to mi chodziło. I Michał dobrze o tym wiedziałeś - co prawda
złośliwie nadepłem na ten ogon, bo.. bo... nudno było i miałem chandrę
- bo wszyscy na urlopach a ja nie mam pracy a jednak nie na urlopie i
zasuwam jak zwykle prawie za darmo.









--
Wacek wszedł na lód i zaczął pękać
{67B14976-ABB4-4A3B-869B-84B5CCA1F569}
icq#: 69691084
Toma
2004-07-26 14:29:24 UTC
Permalink
Użytkownik "Piotr Brzeziński"
Post by Piotr Brzeziñski
Post by Toma
mam problemik z Interbasem i odczytem NULLowej wartosci z Query. W jaki
sposob moge zamienic ja na string? Fieldbyname('nazwa').asstring nie
Witam!
VarToStr(FieldByName('nazwa').AsVariant);
Piotr Brzeziński
k_mail := VarToStr(IBQuery1.Fieldbyname('email').asVariant);
gdzie k_mail to string oczywiscie
i no niestety wciaz to samo - Could not convert... jakies inne pomysly?
miab
2004-07-26 14:36:49 UTC
Permalink
Post by Toma
Witam,
mam problemik z Interbasem i odczytem NULLowej wartosci z Query. W
jaki sposob moge zamienic ja na string? Fieldbyname('nazwa').asstring
nie dziala... caly czas wyskakuje mi blad Could not convert... NULL
into String,
Jakies pomysly?
Oczywiscie chce zamienic NULL na pusty string.
Gdyby to był akurat FireBird 1.5.x.yyyy to np.:
<cy>
New COALESCE internal function

Allow a column value to be calculated by a number of expressions, the first
expression returning a non NULL value is returned as the column value. The
function has the same meaning as NVL in Oracle.

Syntax:

COALESCE (value {, value} ... )

Notes:
COALESCE (V1, V2) is equivalent to the following case specification:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
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

Example:

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)
</cy>

miab
Toma
2004-07-26 14:49:11 UTC
Permalink
Post by Toma
Witam,
mam problemik z Interbasem i odczytem NULLowej wartosci z Query. W
jaki sposob moge zamienic ja na string? Fieldbyname('nazwa').asstring
nie dziala... caly czas wyskakuje mi blad Could not convert... NULL
into String,
Jakies pomysly?
Oczywiscie chce zamienic NULL na pusty string.
No ok ale niestety to IB 6 :) a wiec :)???

Toma
ZPKSoft
2004-07-26 18:30:25 UTC
Permalink
Post by Toma
Post by Toma
Witam,
mam problemik z Interbasem i odczytem NULLowej wartosci z Query. W
jaki sposob moge zamienic ja na string? Fieldbyname('nazwa').asstring
nie dziala... caly czas wyskakuje mi blad Could not convert... NULL
into String,
Jakies pomysly?
Oczywiscie chce zamienic NULL na pusty string.
No ok ale niestety to IB 6 :) a wiec :)???
Witam.
Niedawno walczyłem z tym problemem. Oto wyniki mojej walki :)

1. Jeżeli kolumna tabeli będzie zadeklarowana NOT NULL to nigdy nie będzie
zawierała null tylko np. ''
2; Wartoœć '' nie jest równoważna null !
3. Jeżeli będzie deklaracja np.:
KOLUMNA CHAR(20) NOT NULL
to baza będzie przechowywać wartoœci '' jako stringi ' '
(20- znakowe).
Podczas selekcji np:
SELECT * FROM TABELA WHERE KOLUMNA=''
oraz
SELECT * FROM TABELA WHERE KOLUMNA=' '
lub
SELECT * FROM TABELA WHERE KOLUMNA=' '
zwrócš to samo.
Ta sama zasada dotyczy operacji INSERT, np.:
INSERT INTO TABELA (KOLUMNA) VALUES ('')
i
INSERT INTO TABELA (KOLUMNA) VALUES (' ')
dadzš to samo.
4. Gdy nie zastosujemy NOT NULL to w zapytaniach musimy to uwzględnić, np:
SELECT * FROM TABELA WHERE KOLUMNA='' OR KOLUMNA IS NULL

5. Teraz ostatnia uwaga: proszę spróbować takiej selekcji aby pozbyć się
wartoœci null:
SELECT KOLUMNA ||'' FROM TABELA
powinno pomóc.

Pozdrawiam- Paweł Krzyżanowski.
ZPKSoft
2004-07-26 19:29:36 UTC
Permalink
Pozwolę sobie jeszcze uzupełnić swojš wypowiedŸ:

Delphi odczyta kolumnę z klauzulš NOT NULL jako:
guery['KOLUMNA']=''

Jeżeli chcemy sprawdzać czy wartoœć jest null to:

if guery.fieldByName('KOLUMNA').isNull then ...
else if query['KOLUMNA']='' then ...

Można też tak:

if guery.fieldByName('KOLUMNA').isNull and (query['KOLUMNA']='') then ...

(tu nie będzie błędu bo kompilator sprawdza przed "and" pierwszy człon
wyrażenia,
a gdy jest spełniony to nie sprawdza już drugiego, więc nie musimy pisać
tak:
if guery.fieldByName('KOLUMNA').isNull then
if (query['KOLUMNA']='') then ...)

Lub tak:

try
result:=query['KOLUMNA'];
except
result:='';
end;

(tu pozytywny wynik otrzymujemy także gdy kolumna KOLUMNA nie istnieje, ale
to już inny temat...)

Pozdrawiam-
Paweł Krzyżanowski
szaman
2004-07-27 09:30:01 UTC
Permalink
Post by ZPKSoft
if guery.fieldByName('KOLUMNA').isNull and (query['KOLUMNA']='') then ...
Z tego bym zrobił funkcję i rozwiązanie gotowe.
Post by ZPKSoft
try
result:=query['KOLUMNA'];
except
result:='';
end;
(tu pozytywny wynik otrzymujemy także gdy kolumna KOLUMNA nie istnieje, ale
to już inny temat...)
A inny - poza tym zadziała również gdy kolumna jest ale user nie ma do
niej uprawnień i też dobrze bo program się (prawdopodobnie) nie
wysypie a user nie zobaczy zastrzeżonych dla niego danych.
Co prawda nie wime czy w IB można ustawiac uprawnienia na poziomie pól
ale to juz inna inszość (muszę się dokształcic w tym temacie :-).
--
Szukam pracy.
Yahoo! Messenger: tomek_cwajda
GG : 915593
{67B14976-ABB4-4A3B-869B-84B5CCA1F569}
ZPKSoft
2004-07-27 05:56:59 UTC
Permalink
Ale gafa!

Oczywiœcie pomyliłem się.
Nie powinno być
if guery.fieldByName('KOLUMNA').isNull and (query['KOLUMNA']='') then ...

tylko

if (not guery.fieldByName('KOLUMNA').isNull) and (query['KOLUMNA']<>'') then
...

lub

if guery.fieldByName('KOLUMNA').isNull or (query['KOLUMNA']='') then ...

w zależnoœci od potrzeby. Najmocniej przepraszam. Tak to czasami się zdarza
gdy
pisze się z niczego tzn. z głowy.

Paweł Krzyżanowski.
Loading...