Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2016
    Messaggi
    11

    E' possibile Importare un txt da 3gb in un Db Sql server

    Salve a tutti,

    premetto che non sono ferratissimo nella programmazione, però diciamo che me la cavo.

    Comunque vi presento il problema:

    Ho un Db Access in cui dovrò implementare nuove funzionalità. Queste nuove funzioni si baseranno su dei dati che dovrò importare mensilmente. Dati che saranno contenuti in un txt di quasi 3gb ( e che aumenta nel tempo) . Da quanto ho capito con Access non ho speranze, per cui vorrei sapere come posso fare a importare in SQL Server questo file e aggiornarlo mensilmente e come avviare la procedura dal DbAccess.



    Al momento ho creato il mio DB in SqlServer e creato questa query di importazione:


    codice:
    USE mioDbSQL;
    GO
    DELETE dbo.miaTabella;
    GO
    BULK INSERT dbo.miaTabella
       from 'C:\FileDaImportare.txt'
       with ( formatfile = 'C:\FormatFile.fmt');
    GO
    SELECT * FROM dbo.Miatabella;
    GO
    questo invece è la strutture del formatfile

    codice:
    10.0
    14
    1       SQLCHAR             0       3       ""     1     IDMAR          Latin1_General_CI_AS
    2       SQLCHAR             0       3       ""     2     IDMOD          Latin1_General_CI_AS
    3       SQLCHAR             0       3       ""     3     IDVER          Latin1_General_CI_AS
    4       SQLCHAR             0       20      ""     4     PARNO          Latin1_General_CI_AS
    5       SQLCHAR             0       4       ""     5     IDPAR          Latin1_General_CI_AS
    6       SQLCHAR             0       1       ""     6     TPPAR          Latin1_General_CI_AS
    7       SQLCHAR             0       4       ""     7     IDSIM          Latin1_General_CI_AS
    8       SQLCHAR             0       30      ""     8     ULTDS          Latin1_General_CI_AS
    9       SQLCHAR             0       40      ""     9     PECOS          Latin1_General_CI_AS
    10      SQLCHAR             0       100     ""     10    COLOR          Latin1_General_CI_AS
    11      SQLCHAR             0       12      ""     11    PRZLI          Latin1_General_CI_AS
    12      SQLCHAR             0       1       ""     12    STSPN          Latin1_General_CI_AS
    13      SQLCHAR             0       4       ""     13    IDGRU          Latin1_General_CI_AS
    14      SQLCHAR             0       1       ""     14    Tappo          Latin1_General_CI_AS

    Ovviamente qualcosa non va perchè mi restituisce questo errore:

    codice:
    (0 row(s) affected)
    Msg 4832, Level 16, State 1, Line 1
    Bulk load: An unexpected end of file was encountered in the data file.
    Msg 7399, Level 16, State 1, Line 1
    The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
    Msg 7330, Level 16, State 2, Line 1
    Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".
    
    (0 row(s) affected)
    Vi ringrazio per ogni aiuto e consiglio http://www.tomshw.it/forum/dkstyles/smilies/thanks.gif

  2. #2
    Controllato la correttezza del file CSV? Io di solito carico file file in maniera "raw" e poi la stringa completa la spezzo all'interno di SQL con le funzioni di T-SQL...

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2016
    Messaggi
    11
    Quote Originariamente inviata da LuciferSam86 Visualizza il messaggio
    Controllato la correttezza del file CSV? Io di solito carico file file in maniera "raw" e poi la stringa completa la spezzo all'interno di SQL con le funzioni di T-SQL...
    Si..il format file del file TXT l'ho creato con bcp,exe dalla tabella già importata con lo strumento Import Export di SQL Server.

    Comunque non credo di saper importare un txt in raw..come si fa?! potresti scrivermi le righe di codice?

  4. #4
    Utente di HTML.it L'avatar di nman
    Registrato dal
    Jan 2011
    residenza
    Milano
    Messaggi
    1,333
    Io che sno un semplicione solitamente faccio una miniapplicazione con Access

    Significa che in Access ci metti dentro
    - una tabella collegata al tuo .txt
    - Una INSERT che trasferisce i dati dalla tabella collegata a SQLServer


    Lo trovo comodo perché puoi facilmente e con i semplici
    strumenti di Access validare i dati prima dell'INSERT

    a questo punto mensilmente devi solamente sostituire il tuo .txt


    .

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2016
    Messaggi
    11
    Quote Originariamente inviata da nman Visualizza il messaggio
    Io che sno un semplicione solitamente faccio una miniapplicazione con Access

    Significa che in Access ci metti dentro
    - una tabella collegata al tuo .txt
    - Una INSERT che trasferisce i dati dalla tabella collegata a SQLServer


    Lo trovo comodo perché puoi facilmente e con i semplici
    strumenti di Access validare i dati prima dell'INSERT

    a questo punto mensilmente devi solamente sostituire il tuo .txt


    .
    Ciao,

    sembra interessante..ma mi spieghi meglio?!


    Io avevo tentanto anche di fare così:

    1) creo un DBSQL con una tabella costruita sul file txt ( che già ho)

    2) creo un DBAccess con un query di riempimento che riempie la tabella collegata
    3) creo una importazione salvata che ripeto mensilmente

    ma il file è di 3gb e supera i limiti di Access per cui mi blocca l'importazione.

  6. #6
    Utente di HTML.it L'avatar di nman
    Registrato dal
    Jan 2011
    residenza
    Milano
    Messaggi
    1,333
    Quote Originariamente inviata da T_Manero Visualizza il messaggio
    ..ma mi spieghi meglio?!
    Hai un file .txt ( chiamiamolo Fil.txt )
    crei una applicazione Access ( Chiamiamola App.accdb )
    con la procedura guidata di App.accdb crei una tabella collegata al file Fil.txt ( Chiamiamola TAtxt )
    ( qui devi impiegare un po di tempo per definire bene i criteri di collegamento e il formato dei campi )

    Hai un DB SqlServer ( Chiamiamolo SSQS )
    ti crei in SSQS una tabella che ricevera i dati con gli opportuni campi ( Chiamiamola TDest )

    torniamo da App.accdb e ti crei una tabella collegata a TDest ( Chiamiamola TADest )


    a questo punto nel tuo App.accdb hai 2 tabelle collegate rispettivamente a Fil.txt e a TADest
    giochi in casa ti fai una INSERT del tipo:
    INSERT INTO TADest (campo1, campo2, eccetera) SELECT c1, c2, cecc FROM TAtxt

    avendo specificato il formato dei campi nella TAtxt sei sicuro di inserire solamente dati congrui

    mensilmente devi solamente sostituire fisicamente il Fil.txt di origine e lanciare nuovamente la INSERT


    Quote Originariamente inviata da T_Manero Visualizza il messaggio
    ma il file è di 3gb e supera i limiti di Access per cui mi blocca l'importazione .......
    qui non sono sicurissimo, ma tu con Access lavori solamente su tabelle collegate quindi non ti interessano i 3 GB

    Tuttalpiù se la query di INSERT soffrisse con quella mole da trasferire in una unica botta allora ripieghi su un recordset che trasferisce riga per riga


    Facci sapere come va, diversamente troviamo qualche altra soluzione

    .
    Ultima modifica di nman; 16-03-2016 a 14:01

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2016
    Messaggi
    11
    Ciao ragazzi,

    scusate il ritardo ma avevo accantonato il progetto per altri imprevisti.

    Comunque ho seguito i tuoi consigli di nman e praticamente Access mi ferma allo Step1
    Quote Originariamente inviata da nman Visualizza il messaggio
    con la procedura guidata di App.accdb crei una tabella collegata al file Fil.txt ( Chiamiamola TAtxt )
    Cioè non mi crea Tabelle collegate a files troppo grandi..infatti provando con uno stralcio del file da 50Mb sono andato avanti ed ho creato la tabella TDEST, l'ho collegata ad access tramite ODBC.

    Ora sono fermo all' INSERT, precisamente come avevi in mente di farlo? su un Button, in una query...come?
    potresti farmi un esempio?

  8. #8
    Utente di HTML.it
    Registrato dal
    Mar 2016
    Messaggi
    11
    Quote Originariamente inviata da nman Visualizza il messaggio
    ...diversamente troviamo qualche altra soluzione
    Ragazzi nulla il problema principale resta sempre la grandezza. Seguendo il consiglio di nman ho completato l'operzione..solo che ho dovuto utilizzare un file ridotto a 50Mb.

    Con il file originale, da 3gb, mi compare il seguente avviso:

    Avviso.JPG

    Avete consigli?

  9. #9
    Utente di HTML.it L'avatar di nman
    Registrato dal
    Jan 2011
    residenza
    Milano
    Messaggi
    1,333
    Quote Originariamente inviata da T_Manero Visualizza il messaggio
    ....... Con il file originale, da 3gb, mi compare il seguente avviso: .......
    Si, e vero, nonostante che siano tabelle collegate .......


    allora potresti tentare con una query PassTrought
    che legge riga per riga il tuo .txt
    e fa riga per riga una insert in SQLServer
    ( poi se funziona possiamo fargli inserire dei blocchi da 500/1000 righe)


    ho preparato una demo con un .txt da 4 gb e sta lavorando gia da 10 minuti
    per inserire i 35.000.000 di record in SQLServer

    adesso vado a dormire domani sera ti faccio sapere come è finita


    .

  10. #10
    Utente di HTML.it L'avatar di nman
    Registrato dal
    Jan 2011
    residenza
    Milano
    Messaggi
    1,333
    Quote Originariamente inviata da nman Visualizza il messaggio
    ........ adesso vado a dormire domani sera ti faccio sapere come è finita
    Mi ci sono dovuto intestardire per farlo funzionare

    premesso che il BULKINSERT specifico di SQLServer potrebbe essere la strada più corretta ma che io non ho preso in considerazione

    per fare quel lavoro diversamente potresti usare Access,
    ma non inteso come DB bensi solamente come depositario del codice necessario
    (in effetti basterebbe solamente un file .vbs )

    costruisciti questa demo:


    1°)
    la tabella di SQLServer che ricevera i dati
    codice:
    USE [Test]
    GOSET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[T1](
     [c1Id] [int] NOT NULL,
     [c2dtm] [datetime] NULL,
     [c3nvr] [nvarchar](50) NULL,
     [c4nvr] [nvarchar](50) NULL,
     [c5nvr] [nvarchar](50) NULL,
     [c6nvr] [nvarchar](50) NULL,
     [c7nvr] [nvarchar](50) NULL,
     [c8nvr] [nvarchar](50) NULL,
     CONSTRAINT [PK_T1] PRIMARY KEY CLUSTERED 
    (
     [c1Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO



    2°)
    Il file .txt di 3.6 GB lo ho creato e riempito via codice (Access)
    questo ti crea un file di nome "Prova.txt" nella stessa cartella in cui risiede il file di Access
    (i commenti e spiegazioni sono gia nel codice)
    codice:
    Public Sub CreaTxt()
    
    ' creo nella cartella corrente un file di nome  "Prova.txt"
    ' che contiene 25.000.000 di record  ( sono circa 3.6 GB )
    ' La numerazione va da 10.000.001 a 35.000.000 per rispettare
    ' la lunghezza delle stringhe per la successiva suddivisione in campi
    ' Attenzione non ho fatto il controllo di esistenza,
    ' quindi se hai gia un file di nome "Prova.txt" verra sovrascritto
    
    Dim x As Long
    
    Dim i As Long     ' inizio numerazione 10.000.001
    i = 10000001
    
    Dim f As Long     ' Fine numerazione  35.000.000
    f = 35000000
    '  NB  Per i primi test mettici magari 11000000 come valore di f
    
    
        Open CurrentProject.Path & "\Pova.txt" For Output As #1
        
            For x = i To f
    
                Print #1, x & " " & Now() & " " & String(19, "a") & " " & String(19, "b") & " " & String(19, "c") & " " & String(19, "d") & " " & String(19, "e") & " " & String(19, "f")
    
            Next x
        
        Close #1
    
    ' Sono necessari alcuni minuti
    MsgBox ("Fatto    :) ")
    
    End Sub




    3°)
    Per trasferite dal txt a SQLServer ho abbandonato tutto quanto implica la apertura totale del .txt
    perché sulla mia nacchinina con 2GB di ram non potevo
    pertanto solo del codice con 2 cicli che legge il .txt a blocchi di 300 record ne impacchetta una query di INSERT e la spedisce a mezzo di un PassTrought al SQL
    (al solito i commenti e spiegazioni sono nel codice)
    codice:
    Public Sub Inse4()
    
    Dim Start As Date  ' questo serve solo per il calcolo del tempo
    Start = Now
    
     
    ' Il modello della stringa di query che devo costruire
    '      INSERT INTO [dbo].[T1] ([c1Id] ,[c2dtm], [c3nvr], [c4nvr], [c5nvr], [c6nvr], [c7nvr], [c8nvr]) VALUES
    '      (10000000, N'2016-08-08 12:47:24', N'u3u', N'u4u', N'u5u', N'u6u',N'u7u', N'u8u'),
    '      (10000000, N'2016-08-08 12:47:24', N'u3u', N'u4u', N'u5u', N'u6u',N'u7u', N'u8u'),
    '      (10000000, N'2016-08-08 12:47:24', N'u3u', N'u4u', N'u5u', N'u6u',N'u7u', N'u8u')
    '      ;
    
    
    ' Definisco  E PERSONALIZZO la connessione al DB
    Dim Connes As String
    Connes = "ODBC;DRIVER=SQL Server;SERVER=NomeServer;UID=yyy;PWD=xxxxx;DATABASE=Test"
    
    
    ' Definisco una query (in memoria) con cui inseriro i miei record
    Dim Q As DAO.QueryDef
    Set Q = DBEngine.Workspaces(0).Databases(0).CreateQueryDef("")
    Q.ReturnsRecords = False
    Q.Connect = Connes
    
     
    Dim txtRec As String   ' Il testo del record processato  ( Ancora Senza distinzione di campi )
    
    Dim n As Integer       ' il numeratore del ciclo For Next
    n = 1
    
    Dim s As String        ' la stringa SQL di INSERT
    
    
    
    
    Dim p As Integer       ' la dimensione del pacco di record  ( il massimo del ciclo For Next )
    p = 300    ' 300
    ' Necessario testare la query in relazioni alle dimensioni dei "pacchi" di record che si spediscono
    ' fare pacchi da 1 significa attivare 25.000.000 di volte la INSERT
    ' fare pacchi da 10.000 significa che il pacco ( anche in funzione delle dimensioni dei record )
    '   supera la capacita della RAM o delle stringhe
    '       Devi fare alcuni Test con i dati effettivi e massimizzare
    '       il pacco senza subire in errori ( 3035  Riserve di sistema insufficienti )
    
    
     
    
    ' apriamo il file .txt
    Open CurrentProject.Path & "\Pova.txt" For Input As #1
    
    
    ' ora facciamo il 1° ciclo su tutti i 25.000.000 di record del .txt
    ' il secondo ciclo quando il pacco è pieno provvede alla INSERT
    
    
        Do Until EOF(1)   '1° ciclo inizio ----------------------------------
        
            s = "INSERT INTO [dbo].[T1] ([c1Id] ,[c2dtm], [c3nvr], [c4nvr], [c5nvr], [c6nvr], [c7nvr], [c8nvr]) VALUES " & vbNewLine
    
    
        
            Do Until n > p Or EOF(1)  '2° ciclo inizio ---------------------------------
                Input #1, txtRec       ' Leggo 1 riga
        
                    s = s & "("
                    '  Qui separo la riga del .txt in campi
                    s = s & "" & CLng(Mid(txtRec, 1, 8)) & ", "
                    s = s & "N'" & Format((CDate(Mid(txtRec, 10, 19))), "yyyy-dd-mm hh:nn:ss") & "', "
                    ' non sono sicurissimo sulla formattazione,   ma è una demo
                    s = s & "N'" & Mid(txtRec, 30, 19) & "', "
                    s = s & "N'" & Mid(txtRec, 50, 19) & "', "
                    s = s & "N'" & Mid(txtRec, 70, 19) & "', "
                    s = s & "N'" & Mid(txtRec, 90, 19) & "', "
                    s = s & "N'" & Mid(txtRec, 110, 19) & "', "
                    s = s & "N'" & Mid(txtRec, 130, 19) & "'"
                    '  Fine della separazione in campi
                    s = s & "), " & vbNewLine
                n = n + 1
               
            Loop     '2° ciclo fine ---------------------------------
    
    
            n = 1
            
            ' chiudo la stringa sql e inserto
            s = Left(s, ((InStrRev(s, ",")) - 1)) & vbNewLine & ";"
            'Debug.Print s
            Q.SQL = s
            'Stop
            Q.Execute
               
        Loop      '1° ciclo fine ----------------------------------
    
    
        
        
    ' chiudo tutto
    Close #1
    Q.Close
    
    MsgBox ("Fatto in " & ((Now() - Start) * 1440) & " minuti")
    End Sub

    Facci sapere
    Ultima modifica di nman; 23-03-2016 a 09:05

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.