Программирование >>  Преобразование значений null 

1 ... 183 184 185 [ 186 ] 187 188 189 ... 219


(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



WARD

SALES

CHICAGO

12-SEP-2005

JONES

RESEARCH

DALLAS

12-SEP-2005

MARTIN

SALES

CHICAGO

12-SEP-2005

BLAKE

SALES

CHICAGO

12-SEP-2005

CLARK

ACCOUNTING

NEW YORK

12-SEP-2005

SCOTT

RESEARCH

DALLAS

12-SEP-2005

KING

ACCOUNTING

NEW YORK

12-SEP-2005

TURNER

SALES

CHICAGO

12-SEP-2005

ADAMS

RESEARCH

DALLAS

12-SEP-2005

JAMES

SALES

CHICAGO

12-SEP-2005

FORD

RESEARCH

DALLAS

12-SEP-2005

MILLER

ACCOUNTING

NEW YORK

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)

Следующий шаг - поместить запрос во вложенный запрос и извлечь атрибуты.

SMITH

ALLEN

1600

WARD

1250

JONES

2975

MARTIN

1250

BLAKE

2850

CLARK

2450

SCOTT

3000

KING

5000

TURNER

1500

ADAMS

1100

JAMES

FORD

3000

MILLER

1300


Одно важное замечание: в 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



1 ... 183 184 185 [ 186 ] 187 188 189 ... 219

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика