2012-01-26 15 views
8

Estoy observando una diferencia en cómo Oracle determina un tipo de datos de expresiones de cadena en una instancia de Oracle en particular. El ejemplo más llamativo es el tipo de datos de una cadena vacía: en todas las instancias excepto en una, el tipo de datos es char (0); en ese excepcional es char (32).¿Qué afecta la determinación de Oracle del tipo de datos de expresiones de cadena?

El siguiente script ilustra esto: analiza una declaración simple SELECT '' FROM dual y describe la columna.

=== 
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; 
/
=== 

Devuelve 32 en esta instancia específica y 0 en todas las demás. El siguiente es el resultado de la consulta de NLS_DATABASE_PARAMETERS en ese caso particular:

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 

No difiere de todos los otros casos. Lo único que es diferente es la opción de TDE instalada. Desafortunadamente no tengo una instancia con esta opción instalada y no puedo probarla allí ...

Mi pregunta es si alguien sabe de los factores que pueden influir en la forma en que Oracle determina el tipo de datos de las expresiones de cadena. El caso con cadenas vacías no es el único, pero es el más crítico ya que tenemos una aplicación heredada que emite muchos SELECT con cadenas vacías sin convertirlos a un tipo de datos específico y esa diferencia en el comportamiento de Oracle impide que la aplicación funcione. Cualquier entrada sería apreciada!

Konstantin

+0

Teniendo exactamente el mismo problema y usamos su script para finalmente poder localizarlo, tx. ¿Encontraste una solución? –

+0

No, no lo hice :( –

+0

Hemos abierto un caso con Oracle. Si algo se resuelve, te lo volveré a publicar. –

Respuesta

1

muy curiosa, no puedo replicar esto en 9.2.0.1.0, 10.2.0.1.0, 11.1.0.6.0 o 11.2.0.1.0 y todos ellos tienen cerca de parámetros idénticos (Reino Unido no EE. UU.).

La única posibilidad que se me ocurre es que alguien en algún momento ha iniciado sesión en sys y ha jugado con (alterado) dual. Obviamente he oscurecido el nombre del servidor y 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" 

Su salida debe verse como la anterior. Si es algo diferente, eso explicaría la extrañeza.

+0

él no selecciona nada de dual. Selecciona ''. Dual puede contener una fila con una columna (NUMBER) y el resultado será el mismo. –

+0

No, DUAL no se cambia y solo se usa en este script de prueba. Las declaraciones reales usan tablas reales. Si ayuda de alguna manera, el otro ejemplo de la diferencia en la determinación del tipo de datos es cualquier expresión en una columna VARCHAR2. Por ejemplo, si hay una columna COL del tipo de datos VARCHAR2 (10) y hay una expresión en la lista SELECT rtrim (col), en todas las instancias (10g) intenté que Oracle intente derivar el tipo de datos del tipo de datos de la columna. Aquí devolvería char (10). En esa instancia particular, el resultado siempre es char (4000) ... –

Cuestiones relacionadas