Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Инициализация сложной коллекции  [new]
IMNO
Member

Откуда:
Сообщений: 135
Добрый день.
Чё оно не работает?

declare 
  TYPE matrix_risk_obj IS RECORD (vector1 VARCHAR2(5), vector2 VARCHAR2(5), vector3 VARCHAR2(5), risk VARCHAR2(5)); 
  TYPE matrix_risk_tab IS TABLE OF matrix_risk_obj;
  v_a matrix_risk_tab := matrix_risk_tab(matrix_risk_obj('A', 'B' ,'C' , 'D'));
begin
  NULL;
end;


no fucntion with name 'matrix_risk_obj ' exists in this scope
2 авг 19, 11:26    [21940491]     Ответить | Цитировать Сообщить модератору
 18с+  [new]
-2-
Member

Откуда:
Сообщений: 15330
IMNO,

А причем тут коллекция?
2 авг 19, 11:31    [21940498]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
IMNO
Member

Откуда:
Сообщений: 135
-2-, подразумевается, что matrix_risk_tab будет коллекция объектов matrix_risk_obj.
Я так понимаю, что у меня ошибка в терминологии, и Вы на это обращаете внимание)
В общем, мне надо, чтобы инициализация в примере заработала.
Только что попробовал, если типы объявлены на уровне базы, то всё работает.
2 авг 19, 11:34    [21940502]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
Elic
Member

Откуда:
Сообщений: 29990
RTFM Qualified Expressions (FAQ)
2 авг 19, 13:14    [21940635]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
IMNO
Чё оно не работает?


У RECORD нет конструкторов. Посему:

declare 
  TYPE matrix_risk_obj IS RECORD (vector1 VARCHAR2(5), vector2 VARCHAR2(5), vector3 VARCHAR2(5), risk VARCHAR2(5)); 
  TYPE matrix_risk_tab IS TABLE OF matrix_risk_obj;
  v_a matrix_risk_tab := matrix_risk_tab();
begin
  v_a.extend;
  v_a(1).vector1 := 'A';
  v_a(1).vector2 := 'B';
  v_a(1).vector3 := 'C';
  v_a(1).risk    := 'D';
end;
/


SY.
2 авг 19, 15:15    [21940765]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18370
SY
declare 
  TYPE matrix_risk_obj IS RECORD (vector1 VARCHAR2(5), vector2 VARCHAR2(5), vector3 VARCHAR2(5), risk VARCHAR2(5)); 
  TYPE matrix_risk_tab IS TABLE OF matrix_risk_obj;
  v_a matrix_risk_tab := matrix_risk_tab();
begin
  v_a.extend;
  v_a(1).vector1 := 'A';
  v_a(1).vector2 := 'B';
  v_a(1).vector3 := 'C';
  v_a(1).risk    := 'D';
end;
/

До кучи:
...
  v_a.extend;
  select 'a','b','c','d'
   into v_a(2)
  from dual;

declare r_a  matrix_risk_obj;
begin
  r_a.a = 'a';
  v_a.extend;
  v_a(3) := r_a;
end;
...
2 авг 19, 15:25    [21940772]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
Elic
Member

Откуда:
Сообщений: 29990
SY
У RECORD нет конструкторов.
Ссылочку-таки почитай.
2 авг 19, 15:25    [21940773]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
Elic
SY
У RECORD нет конструкторов.
Ссылочку-таки почитай.


OK. Уточню - до 18C у RECORD нет конструкторов.

SY.
2 авг 19, 15:30    [21940779]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
Elic
Member

Откуда:
Сообщений: 29990
SY
Уточню
"Исправлюсь"?
SY
нет
Правильнее говорить "не было".
2 авг 19, 15:32    [21940783]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18370
Elic
Правильнее говорить "не было".

Эээ... А что, с появлением 18с у record в предыдущих релизов конструкторы появились?
2 авг 19, 15:35    [21940790]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
-2-
Member

Откуда:
Сообщений: 15330
SY
OK. Уточню - до 18C у RECORD нет конструкторов.
Их и в 18с нет.
2 авг 19, 16:03    [21940800]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
-2-
Их и в 18с нет.


A constructor is a special method of a class or structure in object-oriented programming that initializes an object of that type. A constructor is an instance method that usually has the same name as the class, and can be used to set the values of the members of an object, either to default or to user-defined values.


Ну обозвали qualified expression. Обьясни в чем отличие от system defined constructor?

SY.
2 авг 19, 17:46    [21940886]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
-2-
Member

Откуда:
Сообщений: 15330
SY
в чем отличие от system defined constructor?
В том, что переменная типа рекорд, в отличие от объектного, не может быть null. Конструировать нечего.
ссылка
In PL/SQL, we use the terms "qualified expression" and "aggregate" rather than the SQL term "type constructor"
2 авг 19, 17:54    [21940894]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
-2-
В том, что переменная типа рекорд, в отличие от объектного, не может быть null. Конструировать нечего.


Не хочу лезть в дебри философии, но разница в том что переменную объектного тип, как ты и сказал, можно отдельно сначала создать а затем отдельно инициировать с помощью либо системного либо одного из пользоватeльских конструкторов. А можно создать и инициировать "в одном флаконе":

SQL> CREATE OR REPLACE
  2    TYPE MATRIX_RISK_OBJ
  3      IS OBJECT(
  4                VECTOR1 VARCHAR2(5),
  5                VECTOR2 VARCHAR2(5),
  6                VECTOR3 VARCHAR2(5),
  7                RISK VARCHAR2(5)
  8               )
  9  /

Type created.

SQL> BEGIN
  2      DBMS_OUTPUT.PUT_LINE(MATRIX_RISK_OBJ('A','B','C','D').RISK);
  3  END;
  4  /
D

PL/SQL procedure successfully completed.


А с RECORD отдельно сначала создать а затем отдельно инициировать нельзя. RECORD всегда создается и инициируется "в одном флаконе". При декларации все атрибуты инициируются в NULL:

SQL> DECLARE
  2      TYPE MATRIX_RISK_REC
  3        IS RECORD(
  4                  VECTOR1 VARCHAR2(5),
  5                  VECTOR2 VARCHAR2(5),
  6                  VECTOR3 VARCHAR2(5),
  7                  RISK VARCHAR2(5)
  8                 );
  9      V_REC MATRIX_RISK_REC;
 10  BEGIN
 11      DBMS_OUTPUT.PUT_LINE('RISK = "' || V_REC.RISK || '"');
 12      DBMS_OUTPUT.PUT_LINE('RISK = "' || MATRIX_RISK_REC().RISK || '"');
 13      DBMS_OUTPUT.PUT_LINE('RISK = "' || MATRIX_RISK_REC('A','B','C',NULL).RISK || '"');
 14  END;
 15  /
RISK = ""
RISK = ""
RISK = ""

PL/SQL procedure successfully completed.

SQL>


Так что, IMHO, конструктор есть в обоих случаях только с RECORD он применяется "в одном флаконе" с созданием.

SY.

Сообщение было отредактировано: 4 авг 19, 14:48
4 авг 19, 14:46    [21941555]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
iOracleDev
Member

Откуда:
Сообщений: 1029
SY
Так что, IMHO, конструктор есть в обоих случаях только с RECORD он применяется "в одном флаконе" с созданием.

select * into record/object ... ?
4 авг 19, 15:18    [21941566]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
iOracleDev
select * into record/object ... ?


И что подразумевает сей ? Начнем с того чтo select * into object банально не катит. Катит select object_type(col1,...colN) into object_var который создает и инициирует временный обьект object_type(col1,...colN) а затем присваевает его object_var. А вот select * into record это просто для "меньше буковок" и банально означает select * into record.attribute1,...record.attributeN. Никакого RECORD тут не создается.

SY.
4 авг 19, 15:34    [21941572]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
iOracleDev
Member

Откуда:
Сообщений: 1029
SY,

В одном случае нам необходимо использовать конструктор объекта, в другом нет, в случае с записью все делается "под капотом", record не является объектом в pl/sql, мы не работаем с ним как с объектом.

"Никакого RECORD тут не создается." - фетч в коллекцию тоже не приводит к созданию, а чем тогда заполняется коллекция записей?
4 авг 19, 16:02    [21941585]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
iOracleDev
В одном случае нам необходимо использовать конструктор объекта, в другом нет, в случае с записью все делается "под капотом", record не является объектом в pl/sql, мы не работаем с ним как с объектом.

"Никакого RECORD тут не создается." - фетч в коллекцию тоже не приводит к созданию, а чем тогда заполняется коллекция записей?


Ещё раз. Разницу между SELECT OBJECT_TYPE(col1,...colN) INTO OBJECT_VAR и SELECT col1,...colN INTO RECORD_VAR обьяснять не надо? В последнем record, как я и сказал, для "меньше буковок". A вот коллекция RECORD их и создает и инициализирует (конструктор) "в одном флаконе", причем делается это во всех версиях:

SQL> SELECT  BANNER
  2    FROM  V$VERSION
  3  /

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE    10.2.0.5.0      Production
TNS for 64-bit Windows: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - Production

SQL> DECLARE
  2      TYPE MATRIX_RISK_REC
  3        IS RECORD(
  4                  VECTOR1 VARCHAR2(5),
  5                  VECTOR2 VARCHAR2(5),
  6                  VECTOR3 VARCHAR2(5),
  7                  RISK VARCHAR2(5)
  8                 );
  9      TYPE MATRIX_RISK_TAB
 10        IS TABLE OF MATRIX_RISK_REC;
 11      V_REC_TBL MATRIX_RISK_TAB;
 12  BEGIN
 13      SELECT  'A',
 14              'B',
 15              'C',
 16              'D'
 17        BULK  COLLECT
 18        INTO  V_REC_TBL
 19        FROM  DUAL;
 20  END;
 21  /

PL/SQL procedure successfully completed.

SQL> 


BULK COLLECT (остaвим оптимизацию в покое):

a) инициализирует коллекцию
б) extend коллекцию что "в одном флаконе" создает и инициализирует (конструктор) RECORD (все атрибуты инициализуются в NULL)
в) заполняет атрибуты RECORD

Иллюстрация б) в той-же 10G:

DECLARE
    TYPE MATRIX_RISK_REC
      IS RECORD(
                VECTOR1 VARCHAR2(5),
                VECTOR2 VARCHAR2(5),
                VECTOR3 VARCHAR2(5),
                RISK VARCHAR2(5)
               );
    TYPE MATRIX_RISK_TAB
      IS TABLE OF MATRIX_RISK_REC;
    V_REC_TBL MATRIX_RISK_TAB := MATRIX_RISK_TAB(); -- a) инициализирует коллекцию
BEGIN
    V_REC_TBL.EXTEND; -- б) extend коллекцию что "в одном флаконе" создает и инициализирует (конструктор) RECORD (все атрибуты инициализуются в NULL)
    DBMS_OUTPUT.PUT_LINE('RISK = "' || V_REC_TBL(1).RISK || '"');
END;
/
RISK = ""

PL/SQL procedure successfully completed.

SQL> 


Ещё раз - IMHO, конструктор есть в обоих случаях только с RECORD он применяется "в одном флаконе" с созданием.

SY.

Сообщение было отредактировано: 4 авг 19, 16:54
4 авг 19, 16:51    [21941597]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
-2-
Member

Откуда:
Сообщений: 15330
SY
переменную объектного тип, как ты и сказал, можно отдельно сначала создать а затем отдельно инициировать с помощью либо системного либо одного из пользоватeльских конструкторов. А можно создать и инициировать "в одном флаконе
Для понимания, чем "создать" отличается от "инициировать", не хватает примера "создать и не инициировать".

SY
конструктор есть в обоих случаях
Если синтаксический сахар, что вместо повторения переменной на каждое присвоение один раз пишется имя типа, есть конструктор. Тогда и у типа number есть безымянный "конструктор".
4 авг 19, 16:52    [21941598]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
-2-
Если синтаксический сахар, что вместо повторения переменной на каждое присвоение один раз пишется имя типа, есть конструктор. Тогда и у типа number есть безымянный "конструктор".


Я же сказал что INTO RECORD это для "меньше буковок". A вот COLLECTION(RECORD(VAL1,...)), IMHO, нет. Ну не вижу я разницы между MATRIX_RISK_REC(NULL,NULL,NULL,NULL) и MATRIX_RISK_OBJ(NULL,NULL,NULL,NULL). И тот и другой создает RECORD/OBJECT и присваивает каждому отдельному атрибуту указанное значение.

SY.
4 авг 19, 17:22    [21941610]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
iOracleDev
Member

Откуда:
Сообщений: 1029
SY,

Разница простая record - не объект и работать с ним как с объектом нельзя.
4 авг 19, 18:32    [21941654]     Ответить | Цитировать Сообщить модератору
 Re: Инициализация сложной коллекции  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
iOracleDev
Разница простая record - не объект и работать с ним как с объектом нельзя.


Речь шла о том чем qualified expression отличается от конструктора:

Starting with Oracle Database Release 18c, any PL/SQL value can be provided by an expression (for example for a record or for an associative array) like a constructor provides an abstract datatype value. In PL/SQL, we use the terms "qualified expression" and "aggregate" rather than the SQL term "type constructor", but the functionality is the same.

А то что record - не объект это и так понятно.

SY.

Сообщение было отредактировано: 4 авг 19, 18:54
4 авг 19, 18:49    [21941667]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить