powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Непонятность при удалении строк через updatable join view
20 сообщений из 20, страница 1 из 1
Непонятность при удалении строк через updatable join view
    #32142887
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все требования, которые необходимы выполняться для возможности удаления строк в таблице через подобные вью понятны:
- во вью должна быть только одна таблица с сохранением ключей.
Рассмотрим вью построенное из таблиц emp и dept:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
create or replace view emp_v1 as
select 
 e.empno, e.ename, d.dname, d.loc
from 
 emp e,
 dept d
where
 e.deptno = d.deptno
/


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SQL> select * from emp_v1;
     EMPNO ENAME      DNAME      LOC
 ---------- ---------- -------------- -------------
 
       7369  SMITH      RESEARCH       DALLAS
       7499  ALLEN      SALES          CHICAGO
       7521  WARD       SALES          CHICAGO
       7566  JONES      RESEARCH       DALLAS
       7654  MARTIN     SALES          CHICAGO
       7698  BLAKE      SALES          CHICAGO
       7782  CLARK      ACCOUNTING     NEW YORK
       7788  SCOTT      RESEARCH       DALLAS
       7839  KING       ACCOUNTING     NEW YORK
       7844  TURNER     SALES          CHICAGO
       7876  ADAMS      RESEARCH       DALLAS
       7900  JAMES      SALES          CHICAGO
       7902  FORD       RESEARCH       DALLAS
       7934  MILLER     ACCOUNTING     NEW YORK

 14  rows selected.

Для таблицы emp существует primary key для столбца empno:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SQL> select
   2     distinct ucc.table_name, uc.constraint_name, uc.constraint_type, ucc.column_name
   3     from
   4      user_constraints uc,
   5      user_cons_columns ucc
   6    where
   7     uc.table_name = 'EMP' and
   8    ucc.table_name = uc.table_name and
   9    uc.constraint_type='P'
  10   /
TABLE_NAME                     CONSTRAINT_NAME                C COLUMN_NAME
 ------------------------------ ------------------------------ - ---------------
 
EMP                            SYS_C001170                    P EMPNO


Теперь попробуем удалить запись с empno=7369:
Код: plaintext
1.
2.
3.
4.
5.
SQL> delete emp_v1 where empno= 7369 ;
delete emp_v1 where empno= 7369 
       *
ERROR at line  1 :
ORA- 01752 : cannot delete from view without exactly one key-preserved table


Смотрим описание ошибки:
Код: plaintext
1.
2.
3.
4.
5.
ORA- 01752  cannot delete from view without exactly one key-preserved table
Cause: The deleted table either had no key preserved tables, had more than one
key-preserved table, or the key-preserved table was an unmerged view or a
table from a read-only view.
Action: Redefine the view or delete it from the underlying base tables.

Все пречисленные причины отвергаются:
no key preserved table - есть, это таблица emp, у неё есть первичный ключ, который вошёл во вью
had more than one key-preserved table - Тоже неверно, есть еще только одна таблица во вью dept, но она не preserved-key
key-preserved table was an unmerged view or a
table from a read-only view - тоже не подходит.

Теперь попробуем создать первичный ключ для dept для столбца deptno(изначально это нигде не требуется)
Код: plaintext
1.
2.
SQL> alter table dept add primary key(deptno);
Table altered.


Попробуем удалить еще раз:
Код: plaintext
1.
2.
SQL> delete emp_v1 where empno= 7369 ;
 1  row deleted.


Получилось.

Теперь кто мне обьяснит, где сказано что нужен данный первичный ключ для таблицы dept?
Так как во вью должна быть только одна таблица с сохранением ключей и эта таблица emp, то для чего нужно иметь для таблицы dept в данном случае первичный ключ?

Кто спец по updatable join view, кто обьяснит?
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142906
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня есть у самого определённая мысль, что если нет primary key для dept на deptno, то появляется потенциальная возможность в таблице dept иметь для одного и того-же значения deptno несколько строк. В результате во вью столбец empno уже не будет уникальным и будет нарушено уловие key-preserved.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142910
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А попробуйте на deptno вместо primary key unique constraint повесить, интересно будет работать.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142919
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По теории не должно так как unique допускает NULL значение. А key-preserved table по определению не должен содержать NULL значений.
Но щас проверю.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142924
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SQL> alter table dept drop primary key;

Table altered.

SQL> alter table dept add unique(deptno);

Table altered.

SQL> delete emp_v1 where empno= 7369 ;

 1  row deleted.

Сработало однако.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SQL> insert into dept (deptno) values(null);

 1  row created.

SQL> commit;

Commit complete.

SQL> delete emp_v1 where empno= 7521 ;

 1  row deleted.


А вот здесь я уже ничего не понимаю.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142928
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя стоп. NULL же у нас в dept, а не в emp, так что никакой ошибки нет.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142931
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но ведь foreign key может ссылаться не только на primary key в родительской табле но и на любое unique поле. NULLS во вью попасть не должны для них ведь не выполняется where e.deptno = d.deptno, даже если оба операнда NULL. Поэтому может и заработать. Хотя конечно зависит от того, как в Оракл это имплементировали, если решили нельзя значит нельзя.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142944
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выяснилось что можно:-) А если в emp добавить запись с deptno NULL, будет работать? Давайте проверим и это, раз уж вас тестовые таблицы созданы!
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32142948
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я понимаю вам интересно, вы изучаете Oracle :)
Но я могу с вероятность 99.9% сказать что в этом случае точно не получится.
На ради вас...
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143058
_kozyr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть в Application Developer Guide Fundamentals 9i

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
Scenario for Modifying a Join View
The examples in this section use the EMP_TAB and DEPT_TAB tables. However, the
 examples work only if you explicitly define the primary and foreign keys in these
 tables, or define unique indexes. Here are the appropriately constrained table definitions for EMP_TAB and DEPT_TAB:

CREATE TABLE Dept_tab (
        Deptno   NUMBER( 4 ) PRIMARY KEY,
        Dname    VARCHAR2( 14 ),
        Loc      VARCHAR2( 13 ));

CREATE TABLE Emp_tab (
        Empno    NUMBER( 4 ) PRIMARY KEY,
        Ename    VARCHAR2( 10 ),
        Job      varchar2( 9 ),
        Mgr      NUMBER( 4 ),
        Hiredate DATE,
        Sal      NUMBER( 7 , 2 ),
        Comm     NUMBER( 7 , 2 ),
        Deptno   NUMBER( 2 ),
FOREIGN KEY (Deptno) REFERENCES Dept_tab(Deptno));


You could also omit the primary and foreign key constraints listed above, and 
create a UNIQUE INDEX on DEPT_TAB (DEPTNO) to make the following examples 
work.


Должно работать и с NULL DEPTO в EMP судя по всему.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143073
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И все же работает даже если есть нули в обеих таблицах!

Код: plaintext
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.
CREATE TABLE dept
  (id   NUMBER,
   name VARCHAR2( 50 ));

 -- Constraints for DEPT2
 

ALTER TABLE dept
ADD CONSTRAINT id_unq UNIQUE (id);

ALTER TABLE dept
ADD CONSTRAINT nm_unq UNIQUE (name);

insert into dept (id, name) values ( 1 , 'd1');
insert into dept (id, name) values ( 2 , 'd2');
insert into dept (id, name) values (null, 'd3');
insert into dept (id, name) values (null, 'd4');

CREATE TABLE emp
 (id       NUMBER NOT NULL,
  dept_id  NUMBER,
  name     VARCHAR2( 60 ) NOT NULL
 );

 -- Constraints for EMP2
 

ALTER TABLE emp
ADD CONSTRAINT emp_pk PRIMARY KEY (id);

insert into emp (id, dept_id, name) values ( 1 ,  1 , 'e1');
insert into emp (id, dept_id, name) values ( 2 ,  1 , 'e2');
insert into emp (id, dept_id, name) values ( 3 ,  2 , 'e3');
insert into emp (id, dept_id, name) values ( 4 , null, 'e4');
insert into emp (id, dept_id, name) values ( 5 , null, 'e5');

create or replace view emp_view as
select
 emp.id as eid, emp.name as ename, dept.name as dname
from
 emp, dept
where
 emp.dept_id = dept.id;


теперь

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SQL> select * from emp_view;

       EID ENAME      DNAME
 ---------- ---------- ----------
 
          1  e1         d1
          2  e2         d1
          3  e3         d2


ну и

Код: plaintext
1.
2.
SQL> delete from emp_view where eid =  2 ;

 1  row deleted.


Код: plaintext
1.
2.
3.
4.
5.
6.
SQL> select * from emp_view;

       EID ENAME      DNAME
 ---------- ---------- ----------
 
          1  e1         d1
          3  e3         d2
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143093
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня не работал inet, когда я уже подготовил сообщение.
Но что-бы труд не пропал даром, решил всё-же опубликовать
Код: plaintext
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.
SQL>alter table emp drop primary key;

Table altered.

SQL>alter table emp add unique(empno);

Table altered.

SQL>insert into emp (empno) values(NULL);
insert into emp (empno) values(NULL)
            *
ERROR at line  1 :
ORA- 01400 : cannot insert NULL into ( "TEST" . "EMP" . "EMPNO" )


SQL>describe emp;
 Name                                                  Null?    Type
  ----------------------------------------------------- -------- -------------------------------
 
-
 EMPNO                                                 NOT NULL NUMBER( 4 )
 ENAME                                                          VARCHAR2( 10 )
 JOB                                                            VARCHAR2( 9 )
 MGR                                                            NUMBER( 4 )
 HIREDATE                                                       DATE
 SAL                                                            NUMBER( 7 , 2 )
 COMM                                                           NUMBER( 7 , 2 )
 DEPTNO                                                         NUMBER( 2 )

SQL>alter table emp modify(empno NULL);

Table altered.

SQL>insert into emp (empno,deptno) values(NULL, 20 );

 1  row created.

SQL>commit;

Commit complete.

SQL>select * from emp_v1;
     EMPNO ENAME      DNAME      LOC                 VAL1
 ---------- ---------- -------------- ------------- ----------
 
       7499  ALLEN      SALES          CHICAGO              7499 
                      RESEARCH       DALLAS
       7566  JONES      RESEARCH       DALLAS               7566 
       7654  MARTIN     SALES          CHICAGO              7654 
       7698  BLAKE      SALES          CHICAGO              7698 
       7782  CLARK      ACCOUNTING     NEW YORK             7782 
       7788  SCOTT      RESEARCH       DALLAS               7788 
       7839  QUEEN      ACCOUNTING     NEW YORK             7839 
       7844  TURNER     SALES          CHICAGO              7844 
       7876  ADAMS      RESEARCH       DALLAS               7876 
       7900  JAMES      SALES          CHICAGO              7900 
       7902  FORD       RESEARCH       DALLAS               7902 
       7934  MILLER     ACCOUNTING     NEW YORK             7934 

 13  rows selected.

SQL>delete emp_v1 where empno= 7566 ;

 1  row deleted.

SQL>commit;

Commit complete.

SQL>select * from emp_v1;
 cls     EMPNO ENAME      DNAME      LOC                 VAL1
 ---------- ---------- -------------- ------------- ----------
 
       7499  ALLEN      SALES          CHICAGO              7499 
                      RESEARCH       DALLAS
       7654  MARTIN     SALES          CHICAGO              7654 
       7698  BLAKE      SALES          CHICAGO              7698 
       7782  CLARK      ACCOUNTING     NEW YORK             7782 
       7788  SCOTT      RESEARCH       DALLAS               7788 
       7839  QUEEN      ACCOUNTING     NEW YORK             7839 
       7844  TURNER     SALES          CHICAGO              7844 
       7876  ADAMS      RESEARCH       DALLAS               7876 
       7900  JAMES      SALES          CHICAGO              7900 
       7902  FORD       RESEARCH       DALLAS               7902 
       7934  MILLER     ACCOUNTING     NEW YORK             7934 

 12  rows selected.


Мда....
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143100
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Violina:
Мне кажется ваш пример не совсем тот.
Вы NULL добавляете не в тот столбец.

Но мой точно правильный, и при этом работает.
А вроде не должно.
Уточню, что у меня 8i
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143104
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to softbuilder

Вот видите и Вы что то новое узнали. Не зря говорят - обучая мы учимся:-)
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143129
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проверила и в случае вставки NULL в emp.id - работает!
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143134
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про NULL было написано в книге.
В доке Application Developer’s Guide - Fundamentals
Release 2 (8.1.6)
Код: plaintext
1.
2.
3.
4.
5.
Key-Preserved Tables
The concept of a key-preserved table is fundamental to understanding the restrictions
on modifying join views. A table is key preserved if every key of the table can also
be a key of the result of the join. So, a key-preserved table has its keys preserved
through a join.


Может несоответствие версий. В книге вроде как по 8.1.5
Попробую в 8.0.5.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143178
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во результаты тестов на 8.0.5(обращаю внимание именно 8.0.5, а не 8.1.5):
Код: plaintext
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.
SQL> alter table emp modify(empno NULL);

Table altered.

SQL> alter table emp add unique(empno);

Table altered.

SQL> insert into emp (empno,deptno) values(NULL, 20 );

 1  row created.

SQL> commit;

Commit complete.

SQL> delete emp_v1 where empno= 7566 ;
delete emp_v1 where empno= 7566 
       *
ERROR at line  1 :
ORA- 01752 : cannot delete from view without exactly one key-preserved table


SQL> select * from emp_v1;

     EMPNO ENAME      DNAME          LOC
 ---------- ---------- -------------- -------------
 
       7782  CLARK      ACCOUNTING     NEW YORK
       7839  KING       ACCOUNTING     NEW YORK
       7934  MILLER     ACCOUNTING     NEW YORK
       7369  SMITH      RESEARCH       DALLAS
       7876  ADAMS      RESEARCH       DALLAS
       7902  FORD       RESEARCH       DALLAS
       7788  SCOTT      RESEARCH       DALLAS
       7566  JONES      RESEARCH       DALLAS
                      RESEARCH       DALLAS
       7499  ALLEN      SALES          CHICAGO
       7698  BLAKE      SALES          CHICAGO
       7654  MARTIN     SALES          CHICAGO
       7900  JAMES      SALES          CHICAGO
       7844  TURNER     SALES          CHICAGO
       7521  WARD       SALES          CHICAGO

 15  rows selected.


Все вышесказанные утверждения из книги верны для 8.0.5.
В самой книге как я понимаю даётся информация по 8.1.5
8.1.5 у меня нет, есть только 8.1.7
В 8.1.7 эти утверждения не работают.

Вывод: от 8.1.5(которая была близка к 8.1.5) до 8.1.7(которая близка к 9i) произошли определённые изменения.

Вопрос в том, как отвечать на экзамене? :((((
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143196
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, вопросы где нужно найти не просто правильный ответ среди других неправильных, а самый правильный ответ среди более менее правильных, самые каверзные. Остается надеятся что такие вопросы будут привязываться к версии Оракл.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143206
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не хочу открывать новый топик, спрошу здесь. Есть параметры которые можно задать и в конф. файле и потом изменить через команду. Например

The UNDO_RETENTION parameter can be set initially in the initialization parameter file that is used by the STARTUP process:

UNDO_RETENTION = 10

The UNDO_RETENTION parameter value can be changed dynamically at any time using the ALTER SYSTEM command:

ALTER SYSTEM SET UNDO_RETENTION = 5;

Изменится ли после этой команды значение в конф. файле? Я попробовала сама, в файле init.ora вроде ничего не изменилось, но может быть я просто не тот файл смотрела.
...
Рейтинг: 0 / 0
Непонятность при удалении строк через updatable join view
    #32143239
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96521/create.htm#1014422

Но по-моему для PFILE SCOPE не предусмотрена, только для SPFILE.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Непонятность при удалении строк через updatable join view
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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