Visualizzazione dei risultati da 1 a 10 su 13

Visualizzazione discussione

  1. #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.