SL 2005: Importazione dati da file

martedì 11 novembre 2008 - 09.24

paovanm Profilo | Junior Member

Ciao a tutti,

sto cercando di importare dati da file in tabelle di un database SQL 2005 mediante l'utilizzo di stored procedure. Ho trovato una sp che sembra fare a caso mio, questa richiama la funzione 'uftReadfileAsTable' (che ho trovato in rete).

CREATE FUNCTION [dbo].[uftReadfileAsTable]
(
@Path VARCHAR(255),
@Filename VARCHAR(100)
)
RETURNS
@File TABLE
(
[LineNo] INT IDENTITY(1,1),
SavingDateTime VARCHAR(8000),
DataValue VARCHAR(8000)
)

AS
BEGIN

DECLARE @objFileSystem INT,
@objTextStream INT,
@objErrorObject INT,
@strErrorMessage VARCHAR(1000),
@Command VARCHAR(1000),
@hr INT,
@separator INT,
@date VARCHAR(1000),
@val VARCHAR(1000),
@String VARCHAR(8000),
@YesOrNo INT

SELECT @strErrorMessage='opening the File System Object'
EXECUTE @hr = sp_OACreate 'Scripting.FileSystemObject' , @objFileSystem OUT


IF @HR=0 SELECT @objErrorObject=@objFileSystem, @strErrorMessage='Opening file "'+@path+'\'+@filename+'"',@command=@path+'\'+@filename

IF @HR=0 EXECUTE @hr = sp_OAMethod @objFileSystem , 'OpenTextFile'
, @objTextStream OUT, @command,1,false,0--for reading, FormatASCII

WHILE @hr=0
BEGIN
IF @HR=0 SELECT @objErrorObject=@objTextStream,
@strErrorMessage='finding out if there is more to read in "'+@filename+'"'
IF @HR=0 EXECUTE @hr = sp_OAGetProperty @objTextStream, 'AtEndOfStream', @YesOrNo OUTPUT

IF @YesOrNo<>0 BREAK
IF @HR=0 SELECT @objErrorObject=@objTextStream,
@strErrorMessage='reading from the output file "'+@filename+'"'
IF @HR=0 EXECUTE @hr = sp_OAMethod @objTextStream, 'Readline', @String OUTPUT
SELECT @separator = CHARINDEX(' ', @String)
SELECT @date = LEFT(@String, @separator - 1)
SELECT @val = RIGHT(@String, LEN(@string) - @separator)
INSERT INTO @file(SavingDateTime, DataValue) SELECT @date, @val
END
EXECUTE sp_OADestroy @objTextStream
RETURN
END


Ho adattato la situazione al mio caso specifico e tutto sembra essere OK, anche se purtroppo ho dei problemi di velocità di acquisizione, in particolare sembra proprio che sia la funzione uftReadfileAsTable a rallentare la mia importazione (solo che non capisco interamente il suo codice) ... questa funzione è migliorabile? Per esempio non capisco se il file viene letto una volta sola prima del while e poi scorso grazie ad un indice o riletto interamente tutte le volte(non credo)?? come riconosce la fine di ogni riga? Il tempo impiegato da SQ per la lettura di ogni singola riga prescinde dal contenuto della stessa, viene impiegato lo stesso tempo sia che la riga contenga un carattere che ne contenga 10.000..... Qualcuno riesce a farmi avere qualche spiegazione del codice di questa funzione?

Grazie in anticipo,
Michela

lbenaglia Profilo | Guru

>questa funzione è migliorabile?

Ciao Michela,

Certo, utilizzando gli strumenti corretti e non accrocchi del genere.
Leggi sui Books Online il funzionamento del comando BULK INSERT:
http://msdn.microsoft.com/en-us/library/ms188365.aspx

>Grazie in anticipo,
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

paovanm Profilo | Junior Member

Ciao,
con il BulkInsert ho gli stessi tempi di inserimento che avevo precedentemente. A questo punto avrei deciso di proseguire con la funzione 'uftReadfileAsTable'.
Vorrei bypassare il problema delle tempistiche attraverso un unico inserimento massivo di dati in una unica tabella SQL ed un successivo trasferimento degli stessi in tabelle multiple all'interno di SQL. Nel mio caso io ho un centinaio di colonne (che possono essere di numero variabile e separate da tabs) di dati (originariamente su un file di testo) da importare in una tabella SQL. Hai suggerimenti sulla struttura del codice da eseguire in questa operazione?

Grazie,
Michela

lbenaglia Profilo | Guru

>con il BulkInsert ho gli stessi tempi di inserimento che avevo
>precedentemente. A questo punto avrei deciso di proseguire con
>la funzione 'uftReadfileAsTable'.
Hai impostato il recovery model del db a Simple o Bulk Logged?
Hai seguito queste linee guida?
http://msdn.microsoft.com/en-us/library/ms190421.aspx

Le operazioni bulk ti permettono di importare/esportare milioni di righe in una manciata di secondi.

>Grazie,
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

paovanm Profilo | Junior Member

Grazie mille per le tue informazioni!!!
Ci siamo quasi!!!
Ora ho inserito da file 2 colonne con 12.000 dati in un tempo davvero quasi irrisorio!!!
Ora avrei un altro quesito... Ho alcuni files (di appunto qualche decina di migliaia di salvataggi ciascuno) con 2 colonne da inserire in una tabella SQL, a queste 2 colonne dovrei affiancare altre 3 colonne nella tabella SQL con informazioni standard (costanti) per ogni file; come potrei fare per passargli da codice questo valore costante che però non ho all'interno del file?
Grazie ancora,
Michela

lbenaglia Profilo | Guru

>Ora avrei un altro quesito... Ho alcuni files (di appunto qualche
>decina di migliaia di salvataggi ciascuno) con 2 colonne da inserire
>in una tabella SQL, a queste 2 colonne dovrei affiancare altre
>3 colonne nella tabella SQL con informazioni standard (costanti)
>per ogni file; come potrei fare per passargli da codice questo
>valore costante che però non ho all'interno del file?

Direttamente non puoi.
Per stabilire quale sia la strada migliore bisognerebbe entrare nel dettaglio, postando un esempio completo (comandi DDL, file di input, ecc.).

>Grazie ancora,
Prego

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

paovanm Profilo | Junior Member

Ecco una sorta di esempio:

Ho allegato nella cartella zippata esempi di 2 file (ciascuno di 2 colonne) che inseriamo tramite bulk insert nel database (una colonna riempirà il campo SavingDate_Time e l'altra DataValue in sql).

La tabella SQL prevede l'inserimanto di dati in 4 campi, del tipo (come da file allegato):
SavingDate_Time: datetime
KeyTest: varchar(50)
UoM: varchar(8)
DataValue: real

Il KeyTest sarà una foreign key.

Può bastare?
Michela

Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5