2010-09-10 24 views
5

En Oracle, puede crear una tabla temporal usando algo como:SQL Server/Oracle: tablas temporales privadas

CREATE GLOBAL TEMPORARY TABLE temp_table (
    field1 NUMBER, 
    field2 NUMBER 
) 
ON COMMIT DELETE ROWS; 

... que podría ser bastante ingenioso, ya que esto crea una tabla visible para todos, pero los datos que uno inserta en la tabla son visibles solo para él o ella. Además, esos datos se eliminan automáticamente al final de la transacción o de la sesión (según su declaración), dejando intactos los datos temporales de todos los demás.

En SQL Server, sin embargo, puede crear una tabla temporal con:

CREATE TABLE #temp_table (field1 INT, field2 INT); 

... que, como yo lo entiendo, es sustancialmente y funcionalmente diferente de la implementación de Oracle. Esta tabla temporal solo es visible para usted y se descarta (la tabla) inmediatamente después de su uso.

¿Hay alguna capacidad en SQL Server para imitar el comportamiento de Oracle como se describió anteriormente? ¿O la única forma de trabajar con datos temporales implica tener que CREAR repetidamente la tabla temporal con cada iteración de trabajo?

+0

¿Puedes explicar por qué querrías imitar el comportamiento de Oracle en SQLServer? ¿Es solo para evitar el requisito de ejecutar la instrucción CREATE TABLE? –

+0

@Mark ~ bueno, eso principalmente. Pero si estaba lidiando con (1) inserciones de datos temporales repetitivos, (2) con generalmente el mismo formato de datos y campos, (3) y es exclusivo del usuario (es decir, los datos son privados para una sesión de usuario), solo hace mucho más sentido para manejar todo eso en una tabla según la implementación de Oracle. :) –

+0

[Tablas temporales privadas de Oracle] (https://stackoverflow.com/a/48852466/5070879) – lad2025

Respuesta

9

Como ha descubierto SQL Server & Las tablas temporales de Oracle son fundamentalmente diferentes.

En Oracle, las tablas temporales globales son objetos permanentes que almacenan datos temporales específicos de la sesión (o específicos de la transacción).

En SQL Server, las tablas temporales son objetos temporales que almacenan datos temporales, con #temp_tables almacenando datos que son locales a una sesión y ## temp_tables almacenando datos que son globales. (Nunca he tenido necesidad de tablas temporales globales de SQL Server y no sé qué problema resuelven). Si la #temp_table se creó en un procedimiento almacenado, se eliminará cuando el procedimiento almacenado finalice. De lo contrario, se eliminará cuando la sesión se cierre.

Y no, realmente no hay una manera de hacer que SQL Server imite a Oracle. Puede usar una tabla normal con una columna extra almacenando una ID de sesión. Pero no obtendría las ventajas de las tablas temporales con respecto a un menor registro. Tendría que eliminar manualmente los datos temporales. Y lidiar con la limpieza de las sesiones que cesan prematuramente.

EDIT: Otra diferencia entre Oracle y SQL Server es que SQL Server permite que DDL se envuelva en una transacción con otras instrucciones. Entonces, si necesita usar una tabla temporal como parte de una transacción más grande, la declaración create table #table_name... no confirmará implícitamente la transacción actual como lo haría una declaración create table en Oracle.

+0

~ Del mismo modo, no pude entender lo que ocurre con SQL Server ## temp_tables. :) Debo admitir que prefiero tener una implementación como la de Oracle, pero si eso simplemente no es posible en SQL Server, entonces tu sugerencia parece tener más sentido. ¡Gracias! +1 –

+0

Tengo un compañero de trabajo que ha encontrado un uso para ## temp_tables - usa SSIS para algunos procesos y si usa ## en un proceso, y ese proceso llama a otro procesador, proC# 2 puede usar ## temp_table. – user158017

+0

@sql_mommy: Tuve un compañero de trabajo que hizo algo similar, en el sentido de que estaban usando ## tablas para usar a través de procs. Sin embargo, no tenían manera de evitar que los usuarios finales iniciaran el mismo proceso mientras otra persona ya estaba ejecutándose, por lo que corría el riesgo de que el trabajo de los dos usuarios se mezclara en la tabla global de temperaturas. Movimos las definiciones de la tabla temporal al proc superior, de modo que todos los procs llamados pudieran verlas y convertirlas en tablas temporales locales. Para SSIS, si se trata de un proceso por lotes iniciado por un trabajo, probablemente sea correcto. –

1

Esto es fuera de tema, pero ¿sabía usted que en SQL Server puede crear una tabla temporal como esto:

select * 
into #temp_table 
from mytable 
+0

Sí, lo hice. Gracias por señalarlo no obstante. –

1

tablas temporales en SQL puede ser muy útil cuando se necesita para combinar datos de diferentes fuentes que tener un campo de combinación común, pero donde debe sumar los importes antes de la fusión para comparar los totales netos de las dos fuentes. En un sistema financiero que es útil. Me decepcionó cuando pasamos de SQL Server a Oracle porque perdí esa funcionalidad.

El siguiente ejemplo es para una implementación de finanzas PeopleSoft. El módulo de presupuesto (tablas KK) y el libro mayor general (diario) deben tener los mismos saldos para un fondo una vez que la interfaz se haya ejecutado entre los dos.La consulta siguiente totaliza las cantidades presupuestarias por fondo de las tablas KK y las almacena en una tabla temporal, luego suma las cantidades correspondientes por fondo del libro mayor general, luego fusiona las dos tablas de datos pre-sumadas para permitir la comparación de la cantidad neta por fondo las dos fuentes, y enumera los resultados solo cuando hay una diferencia entre los montos de un fondo. En ese caso, los módulos de presupuesto y GL no están sincronizados. Esta es en realidad una solución bastante elegante y no hubo necesidad de crear una tabla temporal global disponible para otros para esta consulta/informe.

Espero que alguien encuentre esto útil. Me ayudó en ese momento.

/*** START NESTED QUERY #1            ***/ 
/*** THE FOLLOWING CREATES TWO TEMP TABLES WITH NET AVAILABLE PER FUND ***/ 
/*** WITH ONE AMOUNT BASED ON KK TABLES AND ONE AMOUNT BASED ON  ***/ 
/*** BUDGETARY GL BALANCES. THEN TEMP TABLES ARE MERGED BY FUND AND ***/ 
/*** NET DIFFERENCE CALCULATED-SELECTING FUNDS WITH DIFFERENCES.  ***/ 
/*** IF BUDGET CHECKING IS COMPLETE AND JOURNALS CREATED AND POSTED ***/ 
/*** THERE SHOULD BE NO DIFFERENCES.         ***/ 

--create a temp table with journal amounts summed by fund code 
CREATE TABLE #JRNLsum(
FUND_CODE char(5), 
JRNLAMT decimal(19,2)) 
INSERT INTO #JRNLsum (FUND_CODE, JRNLAMT) 
select FUND_CODE, sum(MONETARY_AMOUNT * -1) JRNLAMT 
FROM PS_JRNL_LN 
INNER JOIN PS_JRNL_HEADER 
ON PS_JRNL_LN.JOURNAL_ID = PS_JRNL_HEADER.JOURNAL_ID 
where ((ACCOUNT BETWEEN 430000 and 469999) and (FISCAL_YEAR >= '2009')) 
GROUP BY FUND_CODE order by FUND_CODE 


--create a temp table with KK ledger amounts summed by fund code 
CREATE TABLE #KKsum(
FUND_CODE char(5), 
KKAMT decimal(19,2)) 
INSERT INTO #KKsum (FUND_CODE, KKAMT) 
select FUND_CODE, sum(POSTED_TOTAL_AMT * -1) KKAMT 
from PS_LEDGER_KK where LEDGER like 'FUND_%' 
group by FUND_CODE order by FUND_CODE 

--join kk temp date to journal temp data, keep only 
--fund code, kk net amount, and journal net amount 
--and select only fund codes where there is a difference 
--between kk net amount and journal net amount 
select #KKsum.FUND_CODE, JRNLAMT, KKAMT from #JRNLsum 
INNER JOIN #KKsum 
on #KKsum.FUND_CODE=#JRNLsum.FUND_CODE 
where (JRNLAMT - KKAMT) <> 0.00 


--drop the two temp tables 
drop table #KKsum 
drop table #JRNLsum 

/*** END NESTED QUERY #1 
Cuestiones relacionadas