Squeak.ru - шаблоны программирования

INSERT с ORDER в Oracle

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

27.08.2009

  • Зачем тебе это надо? Есть ли какой-то триггер, который что-то делает при вставке? 27.08.2009
  • Связано с stackoverflow.com/questions/ 33841234/ 21.07.2016
  • @zendar Если это похоже на то, что мне нужно было сделать с таблицей «Страны», у кого-то могут быть записи, которые будут привязаны к раскрывающемуся списку или списку на веб-странице, и желательно, чтобы все они были в алфавитном порядке по имени, а не в числовом порядке по ID, и иметь новые записи, которые были добавлены задним числом или из-за текущих событий и вышли из строя, требуя перекодирования страниц для отсортированных раскрывающихся списков/списков, когда вместо этого вы можете просто исправить это в базе данных. 21.07.2016
  • @vapcguy прочитайте первую строку выбранного ответа - без ORDER BY вы не можете знать, в каком порядке Oracle будет возвращать записи, даже если вы вставите их в отсортированном порядке. Ответу семь лет, и он все еще в силе. 23.07.2016
  • @zendar Вы не можете знать, в каком порядке Oracle будет возвращать записи, даже если вы вставите их в отсортированном порядке - Б.С. Как насчет того, чтобы попробовать мой ответ, который я разместил ниже. Вы были против? Я доказал, что могу это сделать. Да, ORDER BY не применяется к обычному INSERT. Добавьте подсказку /*+APPEND*/ из принятого ответа (который он отклонил, поэтому я проголосовал за него и добавил свой собственный пример, где это сработало) и вуаля, это работает! Вот почему ORDER BY существует в первую очередь - если вы добавляете строки в том порядке, в котором они были найдены, именно так вы контролируете свои вставки. 25.07.2016
  • @zendar И почему он отклонил это, так это из-за любого DML или параллельной активности ... может привести к другой физической организации. Хотя, возможно, это так, но когда вы когда-нибудь будете настолько глупы, чтобы сделать это и разрушить свой собственный код, выполняя параллельную деятельность?! Вот почему я не выполняю параллельные операции и использую в своем коде оператор COMMIT, так что этого не происходит! 25.07.2016

Ответы:


1

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

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

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

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

27.08.2009
  • +1 Создание представления должно дать желаемый результат, а также позволит избежать дублирования данных. На самом деле OP упоминает, что они уже используют представление, поэтому, возможно, достаточно просто добавить к нему ORDER BY. 27.08.2009
  • вы не можете надежно контролировать, в каком порядке Oracle хранит строки физически в таблице кучи ... не совсем верно, я думаю. Вставка прямого пути сохранит физический порядок внутри экстентов, поэтому ее можно использовать для улучшения сжатия сегментов данных. Что-то вроде специализированного случая, и, конечно, выбор порядка вовсе не гарантируется. 01.09.2009
  • -1 Надо было сказать, как использовать подсказку /*+APPEND*/, а не просто намекнуть на нее, а потом отмахнуться. Это на самом деле ответ о том, как это сделать! Работал нормально для меня! 20.07.2016

  • 2

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

    27.08.2009

    3

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

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

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

    27.08.2009
  • Вам не нужно контролировать вставку ... См. Ответ @ Винсента. И даже если вы вставите их по порядку, выбор без ORDER BY не удастся (рано или поздно), лучший в этой ситуации - упорядоченный по виду... 27.08.2009

  • 4

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

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

    27.08.2009

    5

    ДА, ЕСТЬ способ контролировать ваш заказ. По опыту я обнаружил, что у меня была таблица стран, назовем ее 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 в своем коде там, где я это делаю, чтобы этого не произошло!

    20.07.2016
  • С признательностью к тем, кто либо проголосовал за себя, либо отменил голосование против — хотел отметить — я уже получил несколько отзывов о том, что это не работает, но мой пример доказывает, что это работает. Если вы хотите защитить возможность параллельных операций, разрушающих его, поэтому я добавил, как избежать этого (кстати, довольно легко сделать) в качестве предостережения, поэтому, пожалуйста, прочитайте весь мой ответ, прежде чем комментировать/голосовать. Кроме того, будучи создаваемой НОВОЙ таблицей, никто не должен даже использовать эту таблицу. Существующие данные копируются, может быть, это отдельная история, но именно поэтому у нас есть периоды обслуживания. Спасибо. 24.02.2017
  • . . Демонстрация того, что код работает один раз, не является гарантией того, что он будет работать всегда. Это все равно, что сказать, что, поскольку 2 + 2 равно 4, прибавление любого целого числа к самому себе всегда равно 4. 21.03.2019
  • @GordonLinoff Да, но, учитывая, что условия, которые я установил выше, почти всегда будут одинаковыми (всегда 2 в вашем примере, а не 3 и т. д.), это почти всегда должно работать. Почти всегда предостережение допускает те сценарии, когда люди используют 3, когда они должны использовать 2: например. вы не можете запускать скрипты в таблицы, так как они изменяются и ожидают идеальных результатов. Вы не можете запускать сценарии в исходных таблицах для копирования данных, если люди вводят в них исходные данные. Такие вещи должны быть само собой разумеющимися. Заблокируйте вещи или создайте копии, а затем замените сделанными вами копиями. 22.03.2019
  • Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...