Создать временная таблица в PL / SQL

Я работаю с базой данных Oracle 10g и хочу извлечь группу записей из одной таблицы, и затем использовать это для извлечения записей из группы связанных таблиц.

Если бы это был T-SQL, я бы сделал это примерно так:

CREATE TABLE #PatientIDs (
  pId int
)

INSERT INTO #PatientIDs
  select distinct pId from appointments

SELECT * from Person WHERE Person.pId IN (select pId from #PatientIDs)

SELECT * from Allergies WHERE Allergies.pId IN (select pId from #PatientIDs)

DROP TABLE #PatientIDs

Однако все полезные страницы, на которые я смотрю, делают это похожим на: гораздо больше работы, чем могло бы быть, поэтому я думаю, что мне не хватает чего-то очевидного.

(Кстати, вместо того, чтобы запускать это как один сценарий, я, вероятно, открою сеанс в Oracle SQL Developer, создаю временную таблицу , а затем запустите каждый запрос, экспортируя их в CSV по мере необходимости. Будет ли это работать?)

6
задан giannis christofakis 19 December 2018 в 11:26
поделиться

3 ответа

Oracle не имеет возможности случайного создания временных таблиц так же, как SQL Server. Вы должны явно создать таблицу в схеме базы данных (create global tempory table). Это также означает, что вам нужны разрешения, позволяющие создавать таблицы, а сценарий должен быть явно развернут как изменение базы данных. Таблица также видна в глобальном пространстве имен.

Это существенное идиоматическое различие между программированием в Oracle и SQL Server. Идиоматический T-SQL может широко использовать временные таблицы, и настоящие требования к написанию процедурного кода T-SQL довольно редки, в основном благодаря этой возможности.

Идиоматический PL/SQL гораздо быстрее переходит к процедурному коду, и вам, вероятно, будет лучше сделать это, чем пытаться подделать временные таблицы. Обратите внимание, что PL/SQL имеет конструкции, ориентированные на производительность, такие как управление потоком для явной параллельной обработки над курсорами и вложенными наборами результатов (курсорные выражения); последние версии имеют JIT-компилятор.

У вас есть доступ к ряду инструментов для быстрого выполнения процедурного кода PL/SQL, и это, вероятно, идиоматическое программирование на PL/SQL. Основополагающая парадигма несколько отличается от T-SQL, и подход к временным таблицам является одной из основных точек, где архитектура системы и идиомы программирования различаются.

6
ответ дан 8 December 2019 в 05:19
поделиться

Хотя точная проблема была решена, если вы хотите развить некоторые полезные навыки в этой области, я бы взглянул на коллекции PL / SQL и, в частности, на массовые операции SQL с использованием коллекций pl / sql (BULK COLLECT / Bulk Binds), предложение RETURNING и определение коллекций с помощью% ROWTYPE.

Вы можете значительно сократить объем кода pl / sql, который вы пишете, понимая все вышесказанное - хотя всегда помните, что решение, полностью основанное на SQL, почти всегда превосходит решение PL / SQL.

5
ответ дан 8 December 2019 в 05:19
поделиться

Oracle имеет временные таблицы, но они требуют явного создания:

create global temporary table...

Данные во временной таблице являются частными для сеанса, который их создал, и могут быть специфичными для сеанса или транзакции- конкретный. Если данные , а не должны быть удалены до завершения сеанса, вам необходимо использовать ON COMMIT PRESERVE ROWS в конце оператора create. Для них также нет поддержки отката или фиксации ...

Я не вижу необходимости во временных таблицах в приведенном вами примере - это рискует, что обновления таблицы APPOINTMENTS , поскольку временная таблица заполнялась, выиграли не отразиться. Используйте IN / EXISTS / JOIN:

SELECT p.* 
  FROM PERSON p
 WHERE EXISTS (SELECT NULL
                 FROM APPOINTMENTS a
                WHERE a.personid = a.id)

SELECT p.* 
  FROM PERSON p
 WHERE p.personid IN (SELECT a.id
                        FROM APPOINTMENTS a)

SELECT DISTINCT p.* 
  FROM PERSON p
  JOIN APPOINTMENTS a ON a.id = p.personid

JOIN рискует дублироваться, если с одной записью PERSON связано более одной записи APPOINTMENT, поэтому я добавил DISTINCT.

12
ответ дан 8 December 2019 в 05:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: