2011-04-05 15 views
7

string'dan decimal'a kadar olan prosedürde, kültür ayarlarında bağımsız ondalık ayırıcı .'u dönüştürmem gerekiyor. Ardından, ondalık sayının sadece .'dan sonra 6 ondalık basamakla sınırlı olduğunu biliyorum ve .'dan önceki rakamların sayısı üzerinde bir sınırlama yok. D önce 9 karakterlerinizleSabit ondalık nokta karakterli TO_NUMBER işlevini kullanarak dizeden dizeye sayı nasıl dönüştürülür?

v_number := TO_NUMBER(v_string, '9999999999999999999999999999999999D999999', 'NLS_NUMERIC_CHARACTERS = ''. '''); 

sayısı maksimum sayıda izin verilir: biçim dizeleri için Oracle belgelerine ve örnekler kullanarak ben şimdi sadece bu çözümü var. Bu biçim dizesini oldukça korkunç buluyorum. Bu genel dönüşüm için daha iyi bir biçim dizesi var mı, yoksa ikinci bir parametre parametresini atmanın bir yolu var mı? Genelde sadece ondalık ayırıcı . ile dönüştürmek istediğimi söylemek için NLS parametresini çalıştırmak için geçmek gerekiyor, ancak ikinci durumda bu durumda da zorunludur.

+0

Dize formundaki sayı her zaman '9999.99999' şeklindeyse, neden sadece TO_NUMBER() kullanıyorsunuz? Ondalıktan sonra 6 basamaklı kısıtlama koymak ister misiniz? – Chandu

+1

@cybernate: 'to_number (: X)', oturumun NLS ayarında X'i ayrıştırır; bu, "." Dan farklı bir sayısal ayırıcıya sahip olabilir. –

+0

@Vincent: Açıklama için Thx ... – Chandu

cevap

7

to_number işlevini üçüncü parametreyle değil, ikinci olarak arayamazsınız. "Çirkin" biçim dizesini bir paket sabitine koymanızı ve unutmamayı öneririm.

Ayrıca, NLS ayarlarınızı değiştirmek ve to_number değişkenini kullanmadan dbms_session.set_nls kullanabilirsiniz.

+1

+1 ... veya aynı düşünceyi kullanarak, kendi "paketlenmiş" işlevinizi "our_to_number" oluşturabilir ve uygulama ayrıntılarını tamamen gizleyebilirsiniz. –

+0

Muhtemelen en net çözüm. Doğru yoldan emin olduğum için teşekkürler. – Tom

0
CREATE OR REPLACE FUNCTION IS_NUMBER(P_VAR IN VARCHAR2) 
RETURN NUMBER 
IS 
    P_NUMBER NUMBER := 0; 
    RIG VARCHAR2(10) := ''; 
    FORMAT VARCHAR2(100) := '999999999999D999999999999'; 
    RES VARCHAR2(100) := ''; 
BEGIN 
    SELECT VALUE INTO RIG 
    FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS'; 
IF SUBSTR(RIG,1,1) = '.' THEN 
RES := REPLACE(P_VAR,',','.'); 
ELSE 
RES := REPLACE(P_VAR,'.',','); 
END IF; 
P_NUMBER := TO_NUMBER(RES,FORMAT,'NLS_NUMERIC_CHARACTERS='''||RIG||''''); 
P_NUMBER := ROUND(P_NUMBER,5); --FIVE DIGITS AFTER DECIMAL POINT IS ENOUGH 
RETURN P_NUMBER; 
EXCEPTION 
WHEN OTHERS THEN RETURN -1; 
END; 
+2

Yorumunuzu Rusça yerine ingilizce olarak yazabilir misiniz? – j0k

+0

ПЯТЬ ЗНАКОВ ПОСЛЕ ЗАПЯТОЙ ДОСТАТОЧНО = Beş ondalıklık yeterlidir. –

-3
select to_number(' 12.5 ') + to_number(' 12 ') from dual; 
+0

Bu soruya nasıl cevap veriyor? –

1

virgül ve dönemi hem Kolları.

FUNCTION to_number2(p_num_str VARCHAR2) RETURN NUMBER AS 
BEGIN 
    RETURN TO_NUMBER(REPLACE(p_num_str, ',', '.'), '999999999999D999999999999', 'NLS_NUMERIC_CHARACTERS=''.,'''); 
END; 
İlgili konular