Звучит так, как будто вы хотите объект с самоописанием.Значение означает программный поиск типа переменной без выбора из некоторого представления метаданных.Просто спросите объект, что вы?
Это кажется ненужным для большинства ситуаций, так как в большинстве случаев мы уже знаем тип (строго типизированный).Например, параметры процедуры обычно указывают тип (число, varchar2, что угодно).Локальные переменные обычно указывают тип или связывают себя с типом объекта базы данных через нотацию% type.
В некоторых ситуациях требуются или могут быть полезны слабо типизированные объекты, например, слабо типизированная переменная курсора, которую можно использоватьдля любого запроса.Чрезмерно упрощенный пример:
create or replace procedure get_data(o_cur OUT SYS_REFCURSOR) as
begin
OPEN o_cur FOR
-- without changing parameter, this could select from any table
select * from emp;
end;
Теперь проблема в том, что у вас могут быть ошибки (во время выполнения), если кто-то кодирует курсор для использования с другой таблицей ( Я специально выбрал ужасное имя процедуры).Примерно так:
declare
l_cur sys_refcursor;
l_row dept%rowtype;
begin
get_data(l_cur);
-- oops, I thought this was dept data when I coded it, Oracle didn't complain at compile time
LOOP
fetch l_cur
into l_row;
exit when l_cur%notfound;
-- do something here
END LOOP;
close l_cur;
end;
По этой же причине я предпочитаю строго типизированные курсоры и избегаю этой ситуации.
В любом случае, в случае объекта с самоописанием, вы можете использовать SYS.ANYDATAвстроенный тип (аналогично SYS.ANYDATASET для универсальных типов коллекций).Это было введено с 9i я верю.Например, эта процедура использует некоторые данные и логику ветвлений в зависимости от типа:
CREATE OR REPLACE procedure doStuffBasedOnType(i_data in sys.anydata) is
l_type SYS.ANYTYPE;
l_typecode PLS_INTEGER;
begin
-- test type
l_typecode := i_data.GetType (l_type);
CASE l_typecode
when Dbms_Types.Typecode_NUMBER then
-- do something with number
dbms_output.put_line('You gave me a number');
when Dbms_Types.TYPECODE_DATE then
-- do something with date
dbms_output.put_line('You gave me a date');
when Dbms_Types.TYPECODE_VARCHAR2 then
-- do something with varchar2
dbms_output.put_line('You gave me a varchar2');
else
-- didn't code for this type...
dbms_output.put_line('wtf?');
end case;
end;
Здесь у вас есть программное ветвление в зависимости от типа.И чтобы использовать это:
declare
l_data sys.anydata;
begin
l_data := sys.anydata.convertvarchar2('Heres a string');
doStuffBasedOnType(l_data);
end;
-- output: "You gave me a varchar2"
Надеюсь, что это не слишком долго заставило задуматься;)