2010-09-10 21 views
5

In Oracle, è possibile creare una tabella temporanea con qualcosa di simile:SQL Server/Oracle: tabelle temporanee private

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

... che potrebbe essere piuttosto carino, in quanto questo crea una tabella visibile a tutti, ma i dati che si inseriscono nella tabella sono visibili solo a lui o lei. Inoltre, tali dati vengono automaticamente cancellati alla fine della transazione o della sessione (a seconda della sua dichiarazione), lasciando incolumi i dati temporanei di tutti gli altri.

In SQL Server, tuttavia, è possibile creare una tabella temporanea con:

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

... che, a quanto mi risulta, è sostanzialmente e funzionalmente diversa rispetto implementazione di Oracle. Questa tabella temporanea è visibile solo a te e viene rilasciata (la tabella) immediatamente dopo l'uso.

Esiste una capacità in SQL Server di imitare il comportamento di Oracle come descritto sopra? O l'unico modo per lavorare con i dati temporanei implica dover ripetutamente CREARE la tabella temporanea con ogni iterazione di lavoro?

+0

puoi spiegare perché vorrebbe simulare il comportamento di Oracle in SQLServer? È solo per evitare il requisito di eseguire l'istruzione CREATE TABLE? –

+0

@ Mark ~ beh, questo principalmente. Ma se avevo a che fare con (1) inserimenti ripetitivi di dati temporanei, (2) con generalmente lo stesso formato di dati e campi, (3) ed è unico per l'utente (cioè i dati sono privati ​​di una sessione utente), rende molto di più senso per gestire tutto ciò che in una tabella secondo l'implementazione di Oracle. :) –

+0

[Tabelle temporanee private Oracle] (https://stackoverflow.com/a/48852466/5070879) – lad2025

risposta

9

Come è stato rilevato SQL Server & le tabelle temporanee Oracle sono fondamentalmente diverse.

In Oracle le tabelle temporanee globali sono oggetti permanenti che memorizzano dati specifici della sessione temporanea (o specifici della transazione).

Nelle tabelle temporanee di SQL Server ci sono oggetti temporanei che memorizzano dati temporanei, con #temp_tables che memorizza dati che sono locali in una sessione e ## temp_tables che memorizzano dati che sono globali. (Non ho mai avuto bisogno di tabelle temporali globali di SQL Server e non so quale problema risolvono.) Se il #temp_table è stato creato in una stored procedure, verrà eliminato quando la stored procedure verrà chiusa. Altrimenti verrà interrotto al termine della sessione.

E no, non c'è davvero un modo per rendere SQL Server simile a Oracle. Potresti usare una tabella normale con una colonna in più che memorizza un ID di sessione. Ma non si otterrebbero i vantaggi delle tabelle temporanee rispetto a una minore registrazione. Dovresti cancellare manualmente i dati temporanei. E si occupano di ripulire dalle sessioni che si interrompono prematuramente.

MODIFICA: Un'altra differenza tra Oracle e SQL Server è che SQL Server consente di includere DDL in una transazione con altre istruzioni. Quindi, se è necessario utilizzare una tabella temporanea come parte di una transazione più grande, l'istruzione non impegna implicitamente la transazione corrente come una dichiarazione create table in Oracle.

+0

~ Allo stesso modo, non riuscivo a capire come usare SQL Server ## temp_tables. :) Certo, preferirei avere un'implementazione come da Oracle, ma se ciò non è semplicemente possibile in SQL Server, allora i tuoi suggerimenti sembrano avere più senso. Grazie! +1 –

+0

Ho un collega che ha trovato un utilizzo per ## temp_tables - usa SSIS per alcuni processi e se si usa ## in un proc e che proc chiama un altro proc, proC# 2 può usare ## temp_table. – user158017

+0

@sql_mommy: Ho avuto un collega che ha fatto una cosa simile, nel senso che stavano usando le tabelle ## per utilizzare procs. Tuttavia, non avevano modo di impedire agli utenti finali di avviare lo stesso processo mentre qualcun altro era già in esecuzione, quindi correva il rischio che il lavoro dei due utenti si mescolasse insieme nella tabella temporanea globale. Abbiamo spostato le definizioni della tabella temporanea nel proc principale, quindi tutti i proc chiamati potrebbero vederli e averli trasformati in tabelle temporanee locali. Per SSIS, se si tratta di un processo batch avviato da un lavoro, probabilmente OK. –

1

Questo è fuori tema, ma lo sapevate che in SQL Server è possibile creare una tabella temporanea come questa:

select * 
into #temp_table 
from mytable 
+0

Sì, l'ho fatto. Grazie per averlo segnalato comunque. –

1

tabelle temporanee in SQL può essere molto utile quando è necessario unire i dati provenienti da fonti diverse che avere un campo unione comune, ma dove è necessario sommare gli importi prima della fusione per confrontare i totali netti per le due origini. In un sistema finanziario che è utile. Sono rimasto deluso quando siamo passati da SQL Server a Oracle perché ho perso questa funzionalità.

L'esempio seguente è per un'implementazione di dati finanziari di PeopleSoft. Il modulo di budget (tabelle KK) e il libro mastro generale (journal) dovrebbero avere gli stessi saldi per un fondo una volta che l'interfaccia è stata gestita tra i due.La query seguente somma gli importi del budget per fondo dalle tabelle KK e memorizza quelli in una tabella temporanea, quindi somma gli importi corrispondenti per fondo dalla contabilità generale, quindi unisce le due tabelle dati pre-sommate per consentire il confronto tra l'importo netto per fondo da le due fonti - ed elenca i risultati solo quando c'è una differenza tra gli importi per un fondo. In tal caso, il budget e i moduli GL non sono sincronizzati. Questa è in realtà una soluzione piuttosto elegante e non è stato necessario creare una tabella temporanea globale disponibile per gli altri utenti per questa query/rapporto.

Spero che qualcuno lo trovi utile. Mi ha aiutato in quel 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 
Problemi correlati