|
Программирование >> Преобразование значений null
(select d.dname,d.loc,sysdate today from dept d where e.deptno=d.deptno) from emp e получаем ошибку, потому что подзапросы в списке оператора SELECT могут возвращать только одно значение. Решение Надо сказать, эта задача довольно нереалистична, потому что простое объединение таблиц EMP и DEPT позволило бы извлекать из DEPT сколько угодно значений. Тем не менее наша задача - сосредоточиться на технике и понять, как применять ее в сценарии, который может оказаться полезным. Обойти требование о возвращении одного значения при размещении оператора SELECT в SELECT (скалярный подзапрос) можно, воспользовавшись преимуществами объектных типов Oracle. Просто определяем объект с несколькими атрибутами и затем работаем с ним как с единой сущностью или ссылаемся на каждый его элемент в отдельности. Фактически правило не нарушено. Получено одно значение, объект, который содержит множество атрибутов. В этом решении используется следующий объектный тип: create type generic ob] as object ( val1 varchar2(10), val2 varchar2(10), val3 date ) Имея в своем распоряжении этот тип, можно выполнить следующий запрос: 1 select x.deptno, 2 x.ename, 3 x.multival.vall dname, 4 x.multival.val2 loc, 5 x.multival.val3 today 6 from ( 7 select e.deptno, 8 e.ename, 9 e.sal, 10 (select generic obj(d.dname,d.loc,sysdate+1) 11 from dept d 12 where e.deptno=d.deptno) multival 13 from emp e 14 ) x DEPTNO ENAME DNAME LOC TODAY 20 SMITH RESEARCH DALLAS 12-SEP-2005 30 ALLEN SALES CHICAGO 12-SEP-2005
Обсуждение Ключ к решению - использовать функцию-конструктор объекта (по умолчанию имя функции-конструктора совпадает с именем объекта). Поскольку объект является единичным скалярным значением, правило скалярных подзапросов не нарушается, как видно из следующего примера: select e.deptno, e.ename, e.sal, (select generic obj(d.dname,d.loc,sysdate-1) from dept d where e.deptno=d.deptno) multival from emp e DEPTNO ENAME SAL MULTIVAL(VAL1, VAL2, VAL3) GENERIC OBJ(RESEARCH, DALLAS, 12-SEP-2005) GENERIC OBJ(SALES, CHICAGO, 12-SEP-2005) GENERIC OBJ(SALES, CHICAGO, 12-SEP-2005) GENERIC OBJ(RESEARCH, DALLAS, 12-SEP-2005) GENERIC OBJ(SALES, CHICAGO, 12-SEP-2005) GENERIC OBJ(SALES, CHICAGO, 12-SEP-2005) GENERIC OBJ(ACCOUNTING, NEW YORK, 12-SEP-2005) GENERIC OBJ(RESEARCH, DALLAS, 12-SEP-2005) GENERIC OBJ(ACCOUNTING, NEW YORK, 12-SEP-2005) GENERIC OBJ(SALES, CHICAGO, 12-SEP-2005) GENERIC OBJ(RESEARCH, DALLAS, 12-SEP-2005) GENERIC OBJ(SALES, CHICAGO, 12-SEP-2005) GENERIC OBJ(RESEARCH, DALLAS, 12-SEP-2005) GENERIC OBJ(ACCOUNTING, NEW YORK, 12-SEP-2005) Следующий шаг - поместить запрос во вложенный запрос и извлечь атрибуты.
Одно важное замечание: в Oracle, в отличие от других СУБД, не обязательно присваивать имена вложенным запросам. Однако в данном конкретном случае дать имя вложенному запросу необходимо, иначе мы не сможем ссылаться на атрибуты объекта. entry:stewiegriffin:lois:brian: entry:moe::sizlack: entry:petergriffin:meg:chris: entry:willie: entry:quagmire:mayorwest:cleveland: entry:::flanders: entry:robo:tchi:ken: Требуется преобразовать эти сериализованные строки в следующее результирующее множество: VAL1 VAL2 VAL3 moe sizlack petergriffin meg chris quagmire mayorwest cleveland robo tchi ken stewiegriffin lois brian willie flanders Решение В каждой сериализованной строке этого примера может храниться до трех значений, разделенных двоеточиями. Но в строке может быть и меньше трех записей. В этом случае необходимо быть внимательным, чтобы разместить доступные записи в соответствующих столбцах результирующего множества. Например, рассмотрим следующую строку: entry:::flanders: Эта строка представляет запись, в которой пропущены первые два значения и присутствует только третье. Поэтому, посмотрев на результирующее множество, приведенное в разделе Задача , можно увидеть, что в строке для flanders в столбцах VAL1 и VAL2 располагаются значения NULL. Ключ к решению - обход строки и сопутствующий ему синтаксический разбор с последующим простым разворачиванием. В данном решении будем работать со строками из представления V, описание которого представлено ниже. В примере используется синтаксис Oracle, но поскольку, кроме функций для синтаксического разбора строк, Синтаксический разбор сериализованных данных в строки таблицы Задача Имеются сериализованные данные (хранящиеся в виде строк), которые необходимо разобрать и возвратить в виде строк таблицы. Например, хранятся следующие данные: STRINGS
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |