Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / PRIMARY KEY в таблице OF XMLTYPE - как? / 10 сообщений из 10, страница 1 из 1
09.10.2020, 21:37
    #40007136
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
ORA 12.2
Зарегистрировал xml-схему.
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.oracle.com/xwarehouses.xsd" xmlns:who="http://www.oracle.com/xwarehouses.xsd" version="1.0" xmlns:oraxdb="http://xmlns.oracle.com/xdb" oraxdb:storeVarrayAsTable="true" oraxdb:flags="2105635" oraxdb:schemaURL="http://www.oracle.com/xwarehouses.xsd" oraxdb:schemaOwner="U99" oraxdb:numProps="11">
  <simpleType name="RentalType">
    <restriction base="string">
      <enumeration value="Rented"/>
      <enumeration value="Owned"/>
    </restriction>
  </simpleType>
  <simpleType name="ParkingType">
    <restriction base="string">
      <enumeration value="Street"/>
      <enumeration value="Lot"/>
    </restriction>
  </simpleType>
  <element name="Warehouse" oraxdb:propNumber="3890" oraxdb:global="true" oraxdb:SQLName="Warehouse" oraxdb:SQLType="Warehouse61_T" oraxdb:SQLSchema="U99" oraxdb:memType="258">
    <complexType oraxdb:SQLType="Warehouse61_T" oraxdb:SQLSchema="U99">
      <sequence>
        <element name="WarehouseId" type="positiveInteger" oraxdb:propNumber="3880" oraxdb:global="false" oraxdb:SQLName="WarehouseId" oraxdb:SQLType="NUMBER" oraxdb:memType="2" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="WarehouseName" type="string" oraxdb:propNumber="3881" oraxdb:global="false" oraxdb:SQLName="WarehouseName" oraxdb:SQLType="VARCHAR2" oraxdb:memType="1" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="Building" type="who:RentalType" oraxdb:propNumber="3882" oraxdb:global="false" oraxdb:SQLName="Building" oraxdb:SQLType="XDB$ENUM_T" oraxdb:SQLSchema="XDB" oraxdb:memType="259" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="Area" type="positiveInteger" oraxdb:propNumber="3883" oraxdb:global="false" oraxdb:SQLName="Area" oraxdb:SQLType="NUMBER" oraxdb:memType="2" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="Docks" type="positiveInteger" oraxdb:propNumber="3884" oraxdb:global="false" oraxdb:SQLName="Docks" oraxdb:SQLType="NUMBER" oraxdb:memType="2" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="DockType" type="string" oraxdb:propNumber="3885" oraxdb:global="false" oraxdb:SQLName="DockType" oraxdb:SQLType="VARCHAR2" oraxdb:memType="1" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="WaterAccess" type="boolean" oraxdb:propNumber="3886" oraxdb:global="false" oraxdb:SQLName="WaterAccess" oraxdb:SQLType="RAW" oraxdb:memType="252" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="RailAccess" type="boolean" oraxdb:propNumber="3887" oraxdb:global="false" oraxdb:SQLName="RailAccess" oraxdb:SQLType="RAW" oraxdb:memType="252" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="Parking" type="who:ParkingType" oraxdb:propNumber="3888" oraxdb:global="false" oraxdb:SQLName="Parking" oraxdb:SQLType="XDB$ENUM_T" oraxdb:SQLSchema="XDB" oraxdb:memType="259" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
        <element name="VClearance" type="positiveInteger" oraxdb:propNumber="3889" oraxdb:global="false" oraxdb:SQLName="VClearance" oraxdb:SQLType="NUMBER" oraxdb:memType="2" oraxdb:MemInline="true" oraxdb:SQLInline="true" oraxdb:JavaInline="true"/>
      </sequence>
    </complexType>
  </element>
</schema>


Пытаюсь создать на её основе XMLTYPE-таблицу.
Если делаю так:
Код: plsql
1.
2.
3.
CREATE TABLE u99.XMLTAB_1
OF XMLTYPE XMLSCHEMA "http://www.oracle.com/xwarehouses.xsd"
ELEMENT "Warehouse";


то запрос проходит без проблем.
Но я хочу иметь в таблице первичный ключ в виде "WarehouseId". Но как его определить в тексте запроса?
Рылся в доках. Для XMLTYPE-вьюх нашёл такоеThe object identifier for uniquely identifying each row in the view can be created using an expression such as extract() with getNumberVal() on the XMLType value . Oracle recommends that you use the extract() operator rather than the member function in the OBJECT IDENTIFIER clause.А в примерах к ним что-то вроде
Код: plsql
1.
EXTRACT(OBJECT_VALUE,'/Emp/@empno').getnumberval()

для выковыривания значения, но никак не могу понять, как это приспособить к моей схеме. Или я вообще не туда рою?



И вторая проблема.
Пытаюсь явно указать OBJECT IDENTIFIER IS при создании xml-таблицы. Но ругается, что недопустимо, если указываю xml-схему. Без явного указания xml-схемы позволяет сделать только OBJECT IDENTIFIER IS SYSTEM GENERATED . Так system-generated и так по умолчанию будет. Как мне указать IS PRIMARY KEY, чтоб его использовала? Что-то вроде:
Код: plsql
1.
2.
3.
4.
5.
6.
CREATE TABLE u99.XMLTAB_1
OF XMLTYPE
... ???
XMLSCHEMA "http://www.oracle.com/xwarehouses.xsd"
ELEMENT "Warehouse"
OBJECT IDENTIFIER IS PRIMARY KEY;
...
Рейтинг: 0 / 0
10.10.2020, 01:49
    #40007188
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
Правильный Вася,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
SQL> CREATE TABLE XML_TBL OF XMLTYPE
  2    VIRTUAL COLUMNS(
  3                    EMPNO AS (
  4                              XMLCAST(
  5                                      XMLQUERY(
  6                                               '/Emp/@empno'
  7                                               PASSING OBJECT_VALUE
  8                                               RETURNING CONTENT
  9                                              )
 10                                      AS NUMBER
 11                                     )
 12                             )
 13                   )
 14  /

Table created.

SQL> ALTER TABLE XML_TBL
  2    ADD CONSTRAINT XML_TBL_PK
  3      PRIMARY KEY(EMPNO)
  4  /

Table altered.

SQL> INSERT
  2    INTO XML_TBL
  3    VALUES(
  4           XMLTYPE('<Emp empno="1">Smith</Emp>')
  5          )
  6  /

1 row created.

SQL> INSERT
  2    INTO XML_TBL
  3    VALUES(
  4           XMLTYPE('<Emp empno="2">Wesson</Emp>')
  5          )
  6  /

1 row created.

SQL> INSERT
  2    INTO XML_TBL
  3    VALUES(
  4           XMLTYPE('<Emp empno="2">Colt</Emp>')
  5          )
  6  /
INSERT
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.XML_TBL_PK) violated


SQL>



В твоем XML PK это WarehouseId.

SY.
...
Рейтинг: 0 / 0
11.10.2020, 23:37
    #40007514
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
Спасибо, но что-то не получается переложить на свою схему.
Пробую так:
Код: plsql
1.
2.
3.
CREATE TABLE XML_TBL OF XMLTYPE XMLSCHEMA "warehouses binary"
ELEMENT "Warehouse"
VIRTUAL COLUMNS( w_id AS ( XMLCAST( XMLQUERY( '/Warehouse/@WarehouseId' PASSING OBJECT_VALUE RETURNING CONTENT ) AS NUMBER ) ) );


РугаетсяORA-19276: XPST0005 - XPath step specifies an invalid element/attribute name: (Warehouse)
Пробовал по-разному путь указать, но элемент всё равно не находит :(



Кстати говоря, VIRTUAL COLUMNS можно указать только тогда, когда схема зарегистрирована как BINARY XML.
...
Рейтинг: 0 / 0
12.10.2020, 09:55
    #40007594
Sah
Sah
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
Правильный Вася,

В примере был XPath на атрибут элемента, а у тебя простой элемент. Попробуй убрать @ в XPath .
...
Рейтинг: 0 / 0
12.10.2020, 20:14
    #40007836
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
Sah
В примере был XPath на атрибут элемента, а у тебя простой элемент. Попробуй убрать @ в XPath .

Да пробовал по-разному путь, в т.ч. и без @
Ошибка всё та же.

Вот код регистрации схемы в БД:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
BEGIN
	DBMS_XMLSCHEMA.REGISTERSCHEMA(
		schemaurl => 'Warehouses',
		schemadoc => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.oracle.com/xwarehouses.xsd"
  xmlns:who="http://www.oracle.com/xwarehouses.xsd"
  version="1.0">

  <simpleType name="RentalType">
    <restriction base="string">
      <enumeration value="Rented"/>
      <enumeration value="Owned"/>
    </restriction>
  </simpleType>
  <simpleType name="ParkingType">
    <restriction base="string">
      <enumeration value="Street"/>
      <enumeration value="Lot"/>
    </restriction>
  </simpleType>
  <element name = "Warehouse">
    <complexType>
      <sequence>
        <element name = "WarehouseId" type = "positiveInteger"/>
        <element name = "WarehouseName" type = "string"/>
        <element name = "Building" type = "who:RentalType"/>
        <element name = "Area" type = "positiveInteger"/>
        <element name = "Docks" type = "positiveInteger"/>
        <element name = "DockType" type = "string"/>
        <element name = "WaterAccess" type = "boolean"/>
        <element name = "RailAccess" type = "boolean"/>
        <element name = "Parking" type = "who:ParkingType"/>
        <element name = "VClearance" type = "positiveInteger"/>
      </sequence>
   </complexType>
 </element>
</schema>',
		gentypes => FALSE,
		gentables => FALSE,
		owner => USER,
		options => DBMS_XMLSCHEMA.REGISTER_BINARYXML
	);
END;



В нём и оригинальный текст схемы без Оракловых довесков, появляющихся после регистрации.
Дальнейшие попытки уже описаны выше. Зашёл в тупик :(
...
Рейтинг: 0 / 0
12.10.2020, 22:20
    #40007874
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
Правильный Вася

Дальнейшие попытки уже описаны выше. Зашёл в тупик :(


Ты бы почитал что есть XML, namespace, etc.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
SQL> BEGIN
  2  DBMS_XMLSCHEMA.REGISTERSCHEMA(
  3  schemaurl => 'http://www.oracle.com/xwarehouses.xsd',
  4  schemadoc => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
  5    targetNamespace="http://www.oracle.com/xwarehouses.xsd"
  6    xmlns:who="http://www.oracle.com/xwarehouses.xsd"
  7    version="1.0">
  8
  9    <simpleType name="RentalType">
 10      <restriction base="string">
 11        <enumeration value="Rented"/>
 12        <enumeration value="Owned"/>
 13      </restriction>
 14    </simpleType>
 15    <simpleType name="ParkingType">
 16      <restriction base="string">
 17        <enumeration value="Street"/>
 18        <enumeration value="Lot"/>
 19      </restriction>
 20    </simpleType>
 21    <element name = "Warehouse">
 22      <complexType>
 23        <sequence>
 24          <element name = "WarehouseId" type = "positiveInteger"/>
 25          <element name = "WarehouseName" type = "string"/>
 26          <element name = "Building" type = "who:RentalType"/>
 27          <element name = "Area" type = "positiveInteger"/>
 28          <element name = "Docks" type = "positiveInteger"/>
 29          <element name = "DockType" type = "string"/>
 30          <element name = "WaterAccess" type = "boolean"/>
 31          <element name = "RailAccess" type = "boolean"/>
 32          <element name = "Parking" type = "who:ParkingType"/>
 33          <element name = "VClearance" type = "positiveInteger"/>
 34        </sequence>
 35     </complexType>
 36   </element>
 37  </schema>',
 38  gentypes => FALSE,
 39  gentables => FALSE,
 40  owner => USER,
 41  options => DBMS_XMLSCHEMA.REGISTER_BINARYXML
 42  );
 43  END;
 44  /

PL/SQL procedure successfully completed.

SQL> CREATE TABLE XML_TBL OF XMLTYPE
  2     XMLSCHEMA "http://www.oracle.com/xwarehouses.xsd"
  3     ELEMENT "Warehouse"
  4     VIRTUAL COLUMNS(
  5                     W_ID AS (
  6                              XMLCAST(
  7                                      XMLQUERY(
  8                                               'xquery version "1.0"; (: :)
  9                                                declare namespace who="http://www.oracle.com/xwarehouses.xsd"; (: :)
 10                                                for $e in /who:Warehouse/WarehouseId
 11                                                  return $e'
 12                                                PASSING OBJECT_VALUE
 13                                                RETURNING CONTENT
 14                                               )
 15                                      AS NUMBER
 16                                     )
 17                             )
 18                    )
 19  /

Table created.

SQL> ALTER TABLE XML_TBL
  2    ADD CONSTRAINT XML_TBL_PK
  3      PRIMARY KEY(W_ID)
  4  /

Table altered.

SQL> INSERT INTO XML_TBL VALUES(
  2                             XMLTYPE.CREATEXML(
  3                                               '<?xml version="1.0"?>
  4                                                <who:Warehouse xmlns:who="http://www.oracle.com/xwarehouses.xsd"
  5                                                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6                                                 xsi:schemaLocation="http://www.oracle.com/xwarehouses.xsd
  7                                                 http://www.oracle.com/xwarehouses.xsd"
  8                                                >
  9                                                  <WarehouseId>1</WarehouseId>
 10                                                  <WarehouseName>WH1</WarehouseName>
 11                                                  <Building>Owned</Building>
 12                                                  <Area>25000</Area>
 13                                                  <Docks>2</Docks>
 14                                                  <DockType>Rear load</DockType>
 15                                                  <WaterAccess>true</WaterAccess>
 16                                                  <RailAccess>false</RailAccess>
 17                                                  <Parking>Street</Parking>
 18                                                  <VClearance>10</VClearance>
 19                                                </who:Warehouse>'
 20                                              )
 21                            )
 22  /

1 row created.

SQL> INSERT INTO XML_TBL VALUES(
  2                             XMLTYPE.CREATEXML(
  3                                               '<?xml version="1.0"?>
  4                                                <who:Warehouse xmlns:who="http://www.oracle.com/xwarehouses.xsd"
  5                                                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6                                                 xsi:schemaLocation="http://www.oracle.com/xwarehouses.xsd
  7                                                 http://www.oracle.com/xwarehouses.xsd"
  8                                                >
  9                                                  <WarehouseId>2</WarehouseId>
 10                                                  <WarehouseName>WH2</WarehouseName>
 11                                                  <Building>Owned</Building>
 12                                                  <Area>25000</Area>
 13                                                  <Docks>2</Docks>
 14                                                  <DockType>Rear load</DockType>
 15                                                  <WaterAccess>true</WaterAccess>
 16                                                  <RailAccess>false</RailAccess>
 17                                                  <Parking>Street</Parking>
 18                                                  <VClearance>10</VClearance>
 19                                                </who:Warehouse>'
 20                                              )
 21                            )
 22  /

1 row created.

SQL> INSERT INTO XML_TBL VALUES(
  2                             XMLTYPE.CREATEXML(
  3                                               '<?xml version="1.0"?>
  4                                                <who:Warehouse xmlns:who="http://www.oracle.com/xwarehouses.xsd"
  5                                                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6                                                 xsi:schemaLocation="http://www.oracle.com/xwarehouses.xsd
  7                                                 http://www.oracle.com/xwarehouses.xsd"
  8                                                >
  9                                                  <WarehouseId>1</WarehouseId>
 10                                                  <WarehouseName>WH1</WarehouseName>
 11                                                  <Building>Owned</Building>
 12                                                  <Area>25000</Area>
 13                                                  <Docks>2</Docks>
 14                                                  <DockType>Rear load</DockType>
 15                                                  <WaterAccess>true</WaterAccess>
 16                                                  <RailAccess>false</RailAccess>
 17                                                  <Parking>Street</Parking>
 18                                                  <VClearance>10</VClearance>
 19                                                </who:Warehouse>'
 20                                              )
 21                            )
 22  /
INSERT INTO XML_TBL VALUES(
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.XML_TBL_PK) violated


SQL>



SY.
...
Рейтинг: 0 / 0
13.10.2020, 01:31
    #40007909
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
SY,
Премного благодарен.
Про XSD и XML читал и продолжаю читать, но английский оригинал тяжеловат для восприятия, с наскока не получается всё сразу осилить.


Кстати, есть странности у созданного виртуального поля:
Код: plsql
1.
2.
3.
4.
5.
6.
SQL> SELECT data_type, nullable, hidden_column, user_generated FROM all_tab_cols
  2  WHERE owner = USER AND table_name = 'XML_TBL' AND column_name = 'W_ID';

DATA_TYPE                               NULLABLE HIDDEN_COLUMN USER_GENERATED
--------------------------------------- -------- ------------- --------------
NUMBER                                  N        YES           NO


1. Оно обнуляемое! Хотя:• A primary key constraint combines a NOT NULL constraint and a unique constraint in a single declaration.
2. Оно почему-то трактуется как скрытое и НЕ юзером созданное, хотя создано явно пользователем и без попыток сделать его невидимым.
...
Рейтинг: 0 / 0
13.10.2020, 01:47
    #40007913
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
Похоже, я нашёл ещё один путь создания первичного ключа в XMLTYPE-таблице, но уже для случая, когда схема зарегистрирована не как BINARY:
Код: plsql
1.
2.
3.
4.
5.
CREATE TABLE xmltab_pk
    OF XMLTYPE ( PRIMARY KEY ( "XMLDATA"."WarehouseId" ) )
    XMLTYPE STORE AS OBJECT RELATIONAL
    XMLSCHEMA "http://www.oracle.com/xwarehouses.xsd"
    ELEMENT "Warehouse";


Не знаю, насколько это легально - использовать внутрисистемные имена полей.


Но как же всё-таки использовать опцию OBJECT IDENTIFIER IS PRIMARY KEY ?
В твоём варианте PK создаётся отдельно, значит при создании таблицы эту опцию не указать.
В моём варианте тоже не даёт, хотя PK определён на этапе создания таблицы.
...
Рейтинг: 0 / 0
13.10.2020, 13:36
    #40008065
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
Правильный Вася

Но как же всё-таки использовать опцию OBJECT IDENTIFIER IS PRIMARY KEY ?


OBJECT IDENTIFIER IS PRIMARY KEY может использоваться только тогда когда PK создан на поле/поля объектного типа.

SY.
...
Рейтинг: 0 / 0
13.10.2020, 21:38
    #40008244
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PRIMARY KEY в таблице OF XMLTYPE - как?
SY
когда PK создан на поле/поля объектного типа

По сути, XMLTYPE - тоже объектный тип, хоть и особенный.

Но даже если это и не совсем так, то как быть с OID_clause в документации XMLTABLE ?
Он там есть, потому и вопрос.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / PRIMARY KEY в таблице OF XMLTYPE - как? / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]