2012-01-26 9 views
8

Obserwuję różnicę w sposobie określania przez Oracle typu danych wyrażeń łańcuchowych na jednej konkretnej instancji Oracle. Najbardziej uderzającym przykładem jest typ danych pustego łańcucha: we wszystkich przypadkach ale jednym typem danych jest char (0); na tym wyjątkowym jest char (32).co wpływa na określenie typów wyrażeń ciągów Oracle?

Poniższy scenariusz ilustruje to: analizuje prostą instrukcję SELECT '' FROM dual i opisuje kolumnę.

=== 
SET SERVEROUTPUT ON 

DECLARE 
    c   NUMBER; 
    col_cnt  INTEGER; 
    rec_tab  DBMS_SQL.DESC_TAB; 
BEGIN 
    DBMS_OUTPUT.PUT_LINE('Testing the datatype of an empty string:'); 
    c := DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE(c, 'SELECT '''' as empty_string FROM dual', DBMS_SQL.NATIVE); 
    DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab); 
    DBMS_OUTPUT.PUT_LINE('max length = ' || rec_tab(1).col_max_len); 
    DBMS_SQL.CLOSE_CURSOR(c); 
END; 
/
=== 

Zwraca 32 w tej konkretnej instancji i 0 na wszystkich pozostałych. Poniżej przedstawiono wynik zapytań nls_database_parameters w tym konkretnym przypadku:

PARAMETER  VALUE 
--------------- --------------- 
NLS_LANGUAGE AMERICAN 
NLS_TERRITORY AMERICA 
NLS_CURRENCY $ 
NLS_ISO_CURRENCY AMERICA 
NLS_NUMERIC_CHARACTERS ., 
NLS_CHARACTERSET WE8MSWIN1252 
NLS_CALENDAR GREGORIAN 
NLS_DATE_FORMAT DD-MON-RR 
NLS_DATE_LANGUAGE AMERICAN 
NLS_SORT BINARY 
NLS_TIME_FORMAT HH.MI.SSXFF AM 
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM 
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR 
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR 
NLS_DUAL_CURRENCY $ 
NLS_COMP BINARY 
NLS_LENGTH_SEMANTICS BYTE 
NLS_NCHAR_CONV_EXCP FALSE 
NLS_NCHAR_CHARACTERSET AL16UTF16 
NLS_RDBMS_VERSION 11.1.0.7.0 
NLS_CSMIG_SCHEMA_VERSION 5 

nie różni się od wszystkich innych przypadkach. Jedyną rzeczą, która jest inna, jest zainstalowana opcja TDE. Niestety nie mam instancji z tą opcją zainstalowaną pod ręką i nie mogę jej przetestować ...

Moje pytanie brzmi, czy ktokolwiek wie o czynnikach, które mogą mieć wpływ na sposób określania przez Oracle typu typów wyrażeń łańcuchowych. Sprawa z pustymi ciągami nie jest jedyna, ale jest najbardziej krytyczna, ponieważ mamy starszą aplikację, która wysyła wiele SELECT z pustymi ciągami bez przesyłania ich do określonego typu danych i ta różnica w zachowaniu Oracle zatrzymuje działanie aplikacji. Wszelkie dane wejściowe zostaną docenione!

Konstantin

+0

Mając dokładnie ten sam problem i wykorzystał twój skrypt, aby w końcu móc go wskazać, tx. Czy zdarzyło Ci się znaleźć rozwiązanie? –

+0

Nie, nie udało mi się :( –

+0

Otworzyliśmy skrzynkę z Oracle .Jeśli coś zostanie rozwiązane, wyślę Ci wiadomość: –

Odpowiedz

1

Bardzo ciekawy, nie mogę na to replikować 9.2.0.1.0, 10.2.0.1.0, 11.1.0.6.0 lub 11.2.0.1.0 i wszyscy mają blisko identycznych parametrach (Wielka Brytania, a nie USA).

Jedyną możliwością, o której mogę myśleć jest to, że ktoś w pewnym momencie zalogował się na sys i grał z (zmienionym) dual. Oczywiście zasłoniłem nazwę serwera i pw ...

[[email protected] ~]$ sqlplus -S "sys/pw as sysdba" 

Session altered. 

desc dual 
Name    Null? Type 
----------------- -------- -------------------------------------------- 
DUMMY      VARCHAR2(1) 

set echo on 
select dbms_lob.substr(dbms_metadata.get_ddl('TABLE','DUAL')) from dual; 

DBMS_LOB.SUBSTR(DBMS_METADATA.GET_DDL('TABLE','DUAL')) 
-------------------------------------------------------------------------------- 

    CREATE TABLE "SYS"."DUAL" 
    ( "DUMMY" VARCHAR2(1) 
    ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 
    STORAGE(INITIAL 16384 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE 
FAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "SYSTEM" 

Twoje dane wyjściowe powinny wyglądać jak powyżej. Jeśli to coś innego, to tłumaczyłoby to obcość.

+0

nie wybiera nic z podwójnego, wybiera "." Podwójny może zawierać wiersz z kolumną (NUMBER), a wynik będzie taki sam. –

+0

Nie, DUAL nie jest zmieniany i jest używany tylko w tym skrypcie testowym. Rzeczywiste instrukcje używają prawdziwych tabel. Jeśli pomaga w jakikolwiek sposób, innym przykładem różnicy w określaniu typów danych jest dowolne wyrażenie w kolumnie VARCHAR2. Na przykład, jeśli istnieje kolumna COL typu danych VARCHAR2 (10) i istnieje wyrażenie na liście SELECT rtrim (col), we wszystkich przypadkach (10g) próbowałem Oracle próbuje wyprowadzić typ danych z typu danych kolumny. Tutaj zwraca char (10). W tej konkretnej instancji wynikiem zawsze jest char (4000) ... –

Powiązane problemy