2010-08-11 30 views
6

Estoy trabajando con una base de datos Oracle 10g, y quiero extraer un grupo de registros de una tabla, y luego usar eso para extraer registros de una serie de tablas relacionadas.Crear una tabla temporal en PL/SQL

Si esto fuera T-SQL, lo haría algo como esto:

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 

Sin embargo, todas las páginas votos miro hacen que este parezca mucho más trabajo de lo que podría ser, así que creo que me falta algo obvio.

(Por cierto, en lugar de ejecutar esto como una secuencia de comandos, probablemente abriré una sesión en Oracle SQL Developer, crearé la tabla temporal, y luego ejecutaré cada consulta, exportándolas a CSV a medida que avance. ese trabajo?)

Gracias!

+0

¿Por qué necesita el paso de tabla temporal? Solo estás reemplazando una selección por otra. ¿La selección inicial es muy cara? ¿O es en caso de que una transacción simultánea cambie las cosas? –

+4

Oracle no es SQL Server, y las situaciones en las que necesitamos utilizar tablas temporales son realmente poco comunes. Lea mi respuesta a esta pregunta similar: http://stackoverflow.com/questions/1192265/local-temporary-table-in-oracle-10-for-the-scope-of-stored-procedure/1193443#1193443 – APC

+0

I fue simplificar, lo que en realidad estaba tratando de hacer fue tomar los últimos 100 pacientes (menos un poco de duplicación). Pero hablarlo más abajo me recordó que podría atrapar a 100 pacientes a partir de la medianoche de esta mañana, y no tener que preocuparme por el cambio de SYSDATE a medida que avanzaba. :-) – SarekOfVulcan

Respuesta

12

Oracle tiene tablas temporales, pero requieren la creación explícita:

create global temporary table... 

Los datos en una tabla temporal es privada para la sesión que lo creó y puede ser específica de la sesión o de transacciones específicas. Si los datos son no que se eliminarán hasta que finalice la sesión, deberá usar ON COMMIT PRESERVE ROWS al final de la instrucción create. Tampoco hay reversión o compromiso de compatibilidad para ellos ...

No veo la necesidad de tablas temporales en el ejemplo que usted dio - existe el riesgo de que las actualizaciones realizadas en la tabla APPOINTMENTS ya que la tabla temporal no se refleje. USO EN/EXISTE/Ingreso:

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 

unirse riesgos duplicados si hay más de uno los registros de cita asociado a un único registro de la persona, por lo que he añadido el DISTINCT.

+0

Esa era la forma en que estaba considerando hacerlo al principio, pero lo estoy filtrando para apptDate SarekOfVulcan

+0

ayer es 'apptdDate> = trunc (sysdate) -1 y apptdDate ThinkJet

5

Si bien el problema exacto se ha resuelto, si desea desarrollar algunas habilidades útiles en esta área, eche un vistazo a las colecciones PL/SQL, y particularmente operaciones SQL a granel utilizando colecciones pl/sql (BULK COLLECT/Bulk Binds), la cláusula RETURNING y definición de colecciones utilizando% ROWTYPE.

Puede reducir drásticamente la cantidad de código pl/sql que escribe a través de la comprensión de todo lo anterior, aunque siempre recuerde que una solución totalmente SQL casi siempre superará una PL/SQL.

6

Oracle no tiene la capacidad de crear casualmente tablas temporales de la misma manera que SQL Server. Debe crear la tabla explícitamente en el esquema de la base de datos (create global tempory table). Esto también significa que necesita permisos que le permiten crear tablas, y la secuencia de comandos debe implementarse explícitamente como un cambio de base de datos. La tabla también es visible en un espacio de nombre global.

Esta es una diferencia idiomática significativa entre la programación de Oracle y SQL Server. Idiomatic T-SQL puede hacer un uso extensivo de tablas temporales y los requisitos genuinos para escribir código de procedimiento T-SQL son bastante raros, sustancialmente debido a esta facilidad.

Idiomatic PL/SQL es mucho más rápido para omitir el código de procedimiento, y es probable que sea mejor hacerlo que intentar falsificar tablas temporales. Tenga en cuenta que PL/SQL tiene construcciones orientadas al rendimiento, como control de flujo para el procesamiento paralelo explícito sobre cursores y conjuntos de resultados anidados (expresiones de cursor); las versiones recientes tienen un compilador JIT.

Tiene acceso a una gama de herramientas para hacer que el código PL/SQL de procedimiento se ejecute rápidamente, y esto es posiblemente una programación idiomática PL/SQL. El paradigma subyacente es algo diferente de T-SQL, y el enfoque de las tablas temporales es uno de los principales puntos donde la arquitectura del sistema y los modismos de programación difieren.

Cuestiones relacionadas