I'm versuchen zu überprüfen, ob ein Wert aus einer Spalte in einer Oracle (10g) Abfrage eine Zahl ist, um es zu vergleichen. Etwas wie:
select case when ( is_number(myTable.id) and (myTable.id >0) )
then 'Is a number greater than 0'
else 'it is not a number'
end as valuetype
from table myTable
Irgendwelche Ideen, wie man das überprüfen kann?
Unter der Annahme, dass die ID-Spalte in "myTable" nicht als NUMBER deklariert ist (was eine seltsame Wahl zu sein scheint und wahrscheinlich problematisch ist), können Sie eine Funktion schreiben, die versucht, die (vermutlich VARCHAR2) ID in eine Zahl zu konvertieren, die Ausnahme abfängt und ein 'Y' oder ein 'N' zurückgibt. Etwas wie
CREATE OR REPLACE FUNCTION is_number( p_str IN VARCHAR2 )
RETURN VARCHAR2 DETERMINISTIC PARALLEL_ENABLE
IS
l_num NUMBER;
BEGIN
l_num := to_number( p_str );
RETURN 'Y';
EXCEPTION
WHEN value_error THEN
RETURN 'N';
END is_number;
Diesen Aufruf können Sie dann in eine Abfrage einbetten, d.h.
SELECT (CASE WHEN is_number( myTable.id ) = 'Y' AND myTable.id > 0
THEN 'Number > 0'
ELSE 'Something else'
END) some_alias
FROM myTable
Beachten Sie, dass PL/SQL zwar einen booleschen Datentyp hat, SQL aber nicht. Während Sie also eine Funktion deklarieren können, die einen Booleschen Wert zurückgibt, können Sie eine solche Funktion nicht in einer SQL-Abfrage verwenden.
Wie ist die Spalte definiert? Wenn es sich um ein varchar-Feld handelt, dann ist es keine Zahl (oder wird als solche gespeichert). Oracle kann zwar die Konvertierung für Sie durchführen (z. B. select * from someTable where charField = 0), aber es gibt nur Zeilen zurück, bei denen die Konvertierung wahr und möglich ist. Dies ist auch in Bezug auf die Leistung alles andere als ideal.
Wenn Sie also Zahlenvergleiche durchführen und diese Spalte als Zahl behandeln wollen, sollte sie vielleicht als Zahl definiert werden?
Davon abgesehen, könnten Sie folgendes tun:
create or replace function myToNumber(i_val in varchar2) return number is
v_num number;
begin
begin
select to_number(i_val) into v_num from dual;
exception
when invalid_number then
return null;
end;
return v_num;
end;
Sie könnten auch die anderen Parameter einbeziehen, die die reguläre to_number hat. Verwenden Sie so:
select * from someTable where myToNumber(someCharField) > 0;
Es werden keine Zeilen zurückgegeben, die Oracle als ungültige Zahl ansieht.
Zum Wohl.
Nun, Sie könnten die Funktion is_number erstellen, die Sie aufrufen, damit Ihr Code funktioniert.
create or replace function is_number(param varchar2) return boolean
as
ret number;
begin
ret := to_number(param);
return true;
exception
when others then return false;
end;
EDIT: Bitte verweisen Sie auf Justin's Antwort. Ich habe dieses kleine Detail für einen reinen SQL-Aufruf vergessen....