Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Определение способа хранения строки в UDT  [new]
Григорий_Косьяненко
Guest
При создании поля таблицы типа varchar2 можно указать размер в char и в byte, затем информацию об этом можно получить из dba_tab_cols, поле char_used.

при создании пользовательского типа данных в нем так же можно задать размер атрибута varchar2 в символах и в байтах, но вот как потом узнать, где что?

В dba_type_attrs этой информации нет.
По умолчанию размер определяется по NLS_LENGTH_SEMANTICS, так же как с таблицами.

Мне нужно привести все UDT к одному виду. Есть ли более простой способ, чем пересоздание их ВСЕХ с явным указанием размера?

Спасибо за помощь.
25 сен 13, 10:31    [14880911]     Ответить | Цитировать Сообщить модератору
 Re: Определение способа хранения строки в UDT  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Григорий_Косьяненко,

SQL> create type tptp as table of varchar2(20 char)
  2  /

Тип создан.

SQL> select dbms_metadata.get_ddl('TYPE','TPTP') from dual;

DBMS_METADATA.GET_DDL('TYPE','TPTP')
------------------------------------------------------------------------


  CREATE OR REPLACE TYPE "FSS"."TPTP" as table of varchar2(20 char)
25 сен 13, 16:09    [14883487]     Ответить | Цитировать Сообщить модератору
 Re: Определение способа хранения строки в UDT  [new]
Григорий_Косьяненко
Guest
orawish, спасибо за ответ.

Я уточню вопрос.

Была база с семантикой BYTE, там создавались UTD без явного указания семантики строковых атрибутов.
Потом семантика базы сменилась на CHAR (не знаю почему и когда), UDT продолжили создавать без явного указания семантики.

И теперь я не могу понять, где у меня поля в символах, где в байтах.

select name,value from v$parameter where name like '%sema%';
nls_length_semantics	BYTE

create or replace type tmp_kga_type as object(
  a1 varchar2(10)
 ,a2 varchar2(10)
);

select dbms_metadata.get_ddl('TYPE','TMP_KGA_TYPE') from dual;

  CREATE OR REPLACE TYPE "EMAIN"."TMP_KGA_TYPE" as object(
  a1 varchar2(10)
 ,a2 varchar2(10)
)

select tmp_kga_type('Первый', 'Второй') from dual;


Вызов, как и ожидается, падает с ошибкой.

alter system set nls_length_semantics='CHAR' scope=both;
-- reboot

select dbms_metadata.get_ddl('TYPE','TMP_KGA_TYPE') from dual;

  CREATE OR REPLACE TYPE "EMAIN"."TMP_KGA_TYPE" as object(
  a1 varchar2(10)
 ,a2 varchar2(10)
)

select tmp_kga_type('Первый', 'Второй') from dual;


Вызов снова падает с ошибкой, хотя теперь основная семантика - символьная. Т.е. он хранится где-то в базе, но не в DDL, который можно получить как из dbms_metadata, так и напрямую из user_source.

select name,value from v$parameter where name like '%sema%';
nls_length_semantics	CHAR

create or replace type tmp_kga_type_2 as object(
  a1 varchar2(10)
 ,a2 varchar2(10)
);

select dbms_metadata.get_ddl('TYPE','TMP_KGA_TYPE_2') from dual;

  CREATE OR REPLACE TYPE "EMAIN"."TMP_KGA_TYPE_2" as object(
  a1 varchar2(10)
 ,a2 varchar2(10)
)

select tmp_kga_type_2('Первый', 'Второй') from dual;
Первый    Второй


Ошибки нет. Т.е. не смотря на то, что DDL одинаковый, база помнит, кто из них в символах, кто в байтах.
Чтобы быть уверенным что все UDT у меня в символах, мне придется пересоздать две сотни типов, что в свою очередь разломает пакеты, где они используются со всеми вытекающими последствиями.

Хотелось бы минимизировать количество пересоздаваемых типов, но для этого нужно знать семантику, в которой они создавались.
В этом и вопрос.
26 сен 13, 09:28    [14885802]     Ответить | Цитировать Сообщить модератору
 Re: Определение способа хранения строки в UDT  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Григорий_Косьяненко
Я уточню вопрос..
..

Хотелось бы минимизировать количество пересоздаваемых типов, но для этого нужно знать семантику, в которой они создавались.
В этом и вопрос.

вопрос интересный. не грех (имхо) и саппорт потревожить
ну а пока, я бы тупо
1) принял, что всё, кроме явного byte имеет семантику char
2) поправил (явно) скрипты из 1) и пересоздал
26 сен 13, 13:01    [14886937]     Ответить | Цитировать Сообщить модератору
 Re: Определение способа хранения строки в UDT  [new]
-2-
Member

Откуда:
Сообщений: 15330
Предположу, что глобално для типа семантика задается через DBA_PLSQL_OBJECT_SETTINGS.NLS_LENGTH_SEMANTICS и может быть изменена через alter type compile
26 сен 13, 13:49    [14887305]     Ответить | Цитировать Сообщить модератору
 Re: Определение способа хранения строки в UDT  [new]
-2-
Member

Откуда:
Сообщений: 15330
alter session set nls_length_semantics=byte;

create or replace type testchby as object(str varchar2(10));
/

select nls_length_semantics from user_plsql_object_settings where name = 'TESTCHBY';

NLS_LENGTH_SEMANTICS    
-------------------------
BYTE                      

select testchby('абвгдейка') from dual;

ORA-22814: атрибут или значение элемента больше заданного типом

alter type testchby compile nls_length_semantics=char;

select nls_length_semantics from user_plsql_object_settings where name = 'TESTCHBY';

NLS_LENGTH_SEMANTICS    
-------------------------
CHAR                      

select testchby('абвгдейка') from dual;

TESTCHBY('АБВГДЕЙКА')        
-----------------------------
RS_DEV.TESTCHBY('абвгдейка') 
26 сен 13, 13:57    [14887355]     Ответить | Цитировать Сообщить модератору
 Re: Определение способа хранения строки в UDT  [new]
Григорий_Косьяненко
Guest
-2-

Спасибо. Это именно то, что я искал.
26 сен 13, 14:07    [14887426]     Ответить | Цитировать Сообщить модератору
 Re: Определение способа хранения строки в UDT  [new]
-2-
Member

Откуда:
Сообщений: 15330
Григорий_Косьяненко
Спасибо. Это именно то, что я искал.
на явно указанный в теле типа byte глобально-типная семантика не сработает.
26 сен 13, 14:09    [14887452]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить