ВСТАВИТЬ с ЗАКАЗАТЬ на Oracle - PullRequest
2 голосов
/ 27 августа 2009

В Oracle 10g нам нужно вставить записи из представления в таблицу для поддержки глупого клиентского приложения, которое не имеет параметров сортировки или ORDER. Есть ли способ контролировать порядок, в котором наш оператор INSERT добавляет записи в таблицу назначения?

Ответы [ 5 ]

11 голосов
/ 27 августа 2009

Вы можете не надежно контролировать, в каком порядке Oracle извлекает строку таблицы без ORDER BY.

Кроме того, без подсказки /*+APPEND*/ Oracle будет физически хранить строки в таблице кучи, где есть место, которого может не быть в конце таблицы!Вы можете подумать, что Oracle вставляет их последовательно, но любое DML или одновременное действие (вставка 2+ сеансов) может привести к другой физической организации.

Вы можете использовать таблицу INDEX ORGANIZED для хранения строкПриказ ПК.После этого самые простые запросы к этой таблице приведут к сортировке набора строк. Однако это не гарантирует, что oracle выберет строки в этом порядке, если вы не укажете ORDER BY (в зависимости от запроса и пути доступа строки могут располагаться в любом порядке).

Вы также можете использовать представление с заказом, это, вероятно, ваш лучший выбор, если вы не можете коснуться приложения (переименуйте таблицу, создайте представление с именем таблицы, дайте приложению думать, что оно запрашиваетстол).Я не знаю, возможно ли это в вашем случае.

5 голосов
/ 27 августа 2009

Если вы не укажете ORDER BY, вы никогда не сможете гарантировать порядок, в котором Oracle будет возвращать строки из SELECT

0 голосов
/ 20 июля 2016

ДА , есть IS способ управления вашим заказом. По опыту я обнаружил, что у меня есть таблица Стран, мы назовем ее OLD_COUNTRIES, которая выглядела так:

-----------------------------------
| ID    |  CODE  |  NAME          |
-----------------------------------
|112099 |  AF    | Afghanistan    |
|112100 |  AA    | Albania        |
|...    |  ..    | ...            |
|112358 |  ZB    | Zimbabwe       |
|112359 |  AZ    | Azores Islands |
|...    |  ..    | ...            |
-----------------------------------

Где я хотел, чтобы элементы, которые были добавлены после основного списка стран (например, Азорские острова и другие острова, которые были добавлены позже), фактически отображались в алфавитном порядке вместе с остальными странами, когда я вставил их в новую таблицу:

CREATE TABLE MYAPP.COUNTRIES
(
    ID NUMBER(*, 0)
  , CODE NVARCHAR2(20)
  , NAME NVARCHAR2(250)
);

Затем я запустил это, чтобы заставить его работать:

INSERT /*+ append */ INTO MYAPP.COUNTRIES (ID, CODE, NAME)
SELECT ID, CODE, NAME FROM MYAPP.OLD_COUNTRIES_TABLE ORDER BY NAME ASC;
COMMIT;

И моя новая таблица COUNTRIES прошла в алфавитном порядке по имени.

ПРИМЕЧАНИЕ : COMMIT требуется, иначе вы получите сообщение об ошибке: ORA-12838: cannot read/modify an object after modifying it in parallel при попытке открыть таблицу для просмотра в Oracle SQL Developer.

ПРИМЕЧАНИЕ : Если вы не используете /*+ append */, он не будет вставлен в указанном вами порядке - он будет игнорировать ORDER BY. И я знаю, что он использовал мой ORDER BY, когда я использовал /*+ append */, а не просто по умолчанию первичный ключ в старых или новых таблицах, потому что ни у одного из них не было первичных ключей.

ПРЕДУПРЕЖДЕНИЕ : Согласно автору принятого ответа, подсказка в приложении, как и в случае "любой DML или одновременной деятельности ... может привести к другой физической организации". Хотя, возможно, и верно, не выполняйте никаких параллельных операций во время этого, и в вашем коде есть оператор COMMIT, где я это делаю, чтобы этого не произошло!

0 голосов
/ 27 августа 2009

Ваша основная проблема, связанная с тем, что ваше приложение не добавляет ORDER BY к своему запросу, может быть решена путем использования индекса столбца (столбцов), по которому вы хотите упорядочить, а затем с помощью сохраненной схемы, чтобы запрос на использование индекса для доступа к таблице.

Вам нужно проверить, будет ли это работать или нет - помните, что, возможно, недостаточно просто добавить подсказку INDEX (), потому что оптимизатор может найти способ выполнить подсказку, не обращаясь к индексу в правильном порядке; и если запрос присоединяется к другим таблицам, порядок может быть в любом случае потерян.

0 голосов
/ 27 августа 2009

Просто используйте ORDER BY. Что-то вроде

INSERT INTO table
(
SELECT 
      column1, column2
FROM 
      view
ORDER BY 
      column2
)

РЕДАКТИРОВАТЬ, это не будет работать на самом деле. Вы можете создать временное представление со строками в соответствующем порядке, а затем выполнить вставку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...