2014-06-09 3 views
8

Così sto cercando di salvare i dati in un database Oracle. Ho una stringa:vera lunghezza di una stringa, come si è visto da Oracle

Väste 

(il nome di uno stato da qualche parte).

Quando faccio un .length() su di esso, ottengo 5, ma quando si salva alla base di dati ottengo:

ORA-12899: value too large for column "dude"."POST_ADR"."STATE_CD" (actual: 6, maximum: 5) 

Quindi, come faccio ad avere la lunghezza "Oracle"?

risposta

5

Perché si sta utilizzando un carattere composto, si dovrebbe ottenere l'array di byte sottostante e quindi ottenere quella lunghezza:

"Väste".getBytes(java.nio.charset.StandardCharsets.UTF_8).length 

stamperà fuori 6 .

+4

È necessario specificare la codifica quando si utilizza getBytes() altrimenti getBytes() dipenderebbe dalla codifica di sistema predefinita. – dimoniy

9

Oracle ti fornisce la lunghezza in byte e "ä" è 2 byte in UTF-8 (c3 a4).

Maggiori informazioni here.

Si può ottenere la lunghezza in byte utilizzando str.getBytes("UTF-8").length

+0

"Allora, come faccio ad ottenere la lunghezza 'oracolo'?" – user2864740

+0

Ovviamente. Quindi, come ottengo la lunghezza di "Oracle"? – markthegrea

0
public static int getByteSize(String content) { 
    int size = 0; 
    if (null != content) { 
     try { 
      size = content.getBytes("utf-8").length; 
     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 
    } 
    return size; 
} 

System.out.println (getByteSize ("vaste")); // 6 System.out.println (getByteSize ("vaaa")); // 7

8

È possibile, come altri hanno dimostrato, convertire la stringa Java in un array di byte utilizzando il set di caratteri del database Oracle e quindi ottenere la lunghezza in byte da questo. Ciò si basa, tuttavia, sulla conoscenza del set di caratteri del tuo database: diversi database avranno set di caratteri diversi che daranno origine a lunghezze di byte diverse per la stessa stringa in set di caratteri diversi.

Supponendo che il database utilizzi un set di caratteri a larghezza variabile come UTF-8 (NLS_CHARACTERSET di AL32UTF8), è anche possibile dichiarare colonne in Oracle in base alla lunghezza del carattere anziché alla lunghezza del byte. Ciò può semplificare il tuo codice poiché puoi semplicemente controllare la lunghezza del carattere della tua stringa. Semplifica anche la comunicazione per gli utenti. È generalmente difficile per utenti di comprendere perché un campo può talvolta memorizzare 5 caratteri mentre altre volte respinge una stringa di 2 caratteri seconda delle caratteri che fanno parte della stringa (1 carattere nel set di caratteri UTF-8 può richiedere fino a 3 byte di stoccaggio).

Per impostazione predefinita, quando si dichiara una colonna

CREATE TABLE foo (
    col_name VARCHAR2(5) 
); 

che indica a Oracle di consentire fino a 5 byte di dati. Se si desidera consentire 5 caratteri di dati, indipendentemente dal numero di byte, tuttavia, è possibile utilizzare caratteri semantica lunghezza

CREATE TABLE foo (
    col_name VARCHAR2(5 CHAR) 
); 

Supponendo che si vuole fare questo per tutte le tabelle durante l'esecuzione DDL, è anche possibile impostare nls_length_semantics a livello di sessione prima di eseguire il DDL

ALTER SESSION SET nls_length_semantics = CHAR; 

CREATE TABLE foo (
    col_name VARCHAR2(5) 
); 

crea una tabella con una colonna che consente fino a 5 caratteri di dati.

+0

Ciao, Come posso ottenere dal codice effettivo encondig di colonna/tabella? Io non sono possibile se il mio codice viene eseguito su UTF-8 o UTF-16 base – TNN

+0

@TNN - 'v $ nls_parameters' ti dirà il database e il carattere nazionale impostato. Le colonne 'char',' varchar2' e 'clob' usano il set di caratteri del database. Le colonne 'nchar',' nvarchar2' e 'nclob' usano il set di caratteri nazionale. Non c'è modo di scegliere un set di caratteri diverso per una particolare tabella o colonna. –

+0

Grazie, è un lavoro – TNN