Slik holder rad orden med SqlBulkCopy?

stemmer
3

Jeg eksportere data auto fra Excel til SQL Server 2005 ved hjelp SqlBulkCopy. Det fungerer bra, det eneste problemet jeg har er at den ikke bevare rad sekvens jeg har i Excel-filen. Jeg har ikke en kolonne på bestilling av, jeg vil bare postene som skal settes inn i samme rekkefølge som de vises i Excel regneark.

Jeg kan ikke endre Excel-filen, og må jobbe med det jeg har. Sortering av et hvilket som helst av de eksisterende kolonner vil bryte sekvensen.

Vennligst hjelp.

PS Endte opp å sette inn ID-kolonnen i regnearket, ser ut som det er ingen måte å holde orden under eksport / import

Publisert på 09/10/2008 klokken 22:28
kilden bruker
På andre språk...                            


4 svar

stemmer
0

Hvis du kan lagre Excel-regneark som CSV er det veldig enkelt å generere en liste med INSERT-setninger med noen skriptspråk som vil bli utført i samme rekkefølge som i regnearket. Her er en rask eksempel i Groovy men noen skriptspråk vil gjøre det like lett hvis ikke enklere:

def file1 = new File('c:\\temp\\yourSpreadsheet.csv')
def file2 = new File('c:\\temp\\yourInsertScript.sql')

def reader = new FileReader(file1)
def writer = new FileWriter(file2)

reader.transformLine(writer) { line ->
    fields =  line.split(',')

    text = """INSERT INTO table1 (col1, col2, col3) VALUES ('${fields[0]}', '${fields[1]}', '${fields[2]}');"""

}

Du kan deretter utføre dine "yourInsertScript.sql" mot databasen og din bestilling vil være den samme som regnearket.

Svarte 09/10/2008 kl. 22:41
kilden bruker

stemmer
3

Jeg tror ikke at rad bestilling er spesifisert eller garantert av SQL med mindre du bruker en "ORDER BY" klausulen.

Fra et innlegg av Bill Vaughn ( http://betav.com/blog/billva/2008/08/sql_server_indexing_tips_and_t.html ):

Bruke Order By: Selv når en tabell har et klyngeindeks (som lagrer data i fysisk rekkefølge), ikke SQL Server ikke garantere at rader vil bli returnert i det (eller noen spesiell) for mindre en ORDER BY-ledd benyttes.

En annen link med info:

http://sqlblogcasts.com/blogs/simons/archive/2007/08/21/What-is-the-position-of-a-row--.aspx

Svarte 09/10/2008 kl. 22:44
kilden bruker

stemmer
0

Du kan også være i stand til å definere en identitet kolonne i tabellen at auto-trinn under data belastning. På den måten kan du sortere på det senere når du vil postene i samme rekkefølge igjen.

Svarte 09/10/2008 kl. 22:44
kilden bruker

stemmer
1

Etter mye forskning synes det klart at det er ingen måte å beholde rad for med Bulk Sett inn kommando skrevet som det er kjennetegnet av Microsoft. Du må enten legge til en ID-kolonne deg direkte inn i importfilen, må du bruke et skall eller en annen ekstern script, eller du kan gjøre uten. Det synes det ville være en nødvendig (og enkel) funksjon for Microsoft å legge til, men etter mer enn et tiår med noe fra dem, er det ikke kommer til å skje.

Likevel trengte jeg å bevare selve posten orden i importfilen etter import som høyere opp postene vil avløse de lavere hvis et sett kolonne hadde samme verdi.

Så jeg gikk en annen rute. Mine begrensninger var:

  • Jeg kunne ikke endre kildefilen i det hele tatt. (Og sette en dårlig presedens!)
  • Jeg kan ikke bruke en ekstern script. For komplisert. Det måtte være en enkel T-SQL basert løsning, ingen CMD henrettelser. Dette er nødvendig for å gå inn i en enkelt prosedyre slik at det kunne være automatisert.

Jeg likte logikken i å bruke Powershell for å opprette bestilt sette inn uttalelser for hver rad, deretter kjører i SQL. Det var i hovedsak kø hver post opp for individuell innsats heller enn BULK innsats. Ja, det ville fungere, men det vil også være veldig treg. Jeg har ofte filer med 500K + rader i dem. Jeg trengte noe raskt.

Så jeg kjørte over XML. Bulk laste opp filen direkte inn i et enkelt XML variabel. Dette ville beholde rekkefølgen på postene som hver er lagt til XML. Deretter parse XML variable og sette resultatene inn i en tabell, og legger en identitet kolonne på samme tid.

Det er en forutsetning at importfilen er en standard tekstfil, med hver post som ender i et linjeskift (Char (13) + Char (10))

Min tilnærming har 2 trinn:

  1. Utføre IMPORT SQL-setning (ved hjelp OpenRowSet), innkapsle hver post med XML-koder. Fange resultatene i en XML-variabel.

  2. Analyser variabelen med XML-koder inn i en tabell, og legger en inkrementering kolonne [ID].

    ---------------------------------
    Declare @X xml;
    ---------------------------------
    SELECT @X=Cast('<X>'+Replace([BulkColumn],Char(13)+Char(10),'</X><X>')+'</X>' as XML)
    FROM OPENROWSET (BULK N'\\FileServer\ImportFolder\ImportFile_20170120.csv',SINGLE_CLOB) T
    ---------------------------------
    SELECT [Record].[X].query('.').value('.','varchar(max)') [Record]
    ,ROW_NUMBER() OVER (ORDER BY (SELECT 100)) [ID]
    --Into #TEMP 
    FROM @X.nodes('X') [Record](X);
    ---------------------------------
    
    • XML-koder erstatte hvert linjeskift.

    • Hvis filen slutter med et linjeskift, vil dette føre til en tom rad for å bli lagt til på slutten. Bare slette den siste raden.

Jeg skrev dette i min prosedyre ved hjelp av dynamisk sql så jeg kunne passere i filnavnet og angi ID for å begynne på en eller 0 (i tilfelle det er en header rad).

Jeg var i stand til å kjøre denne mot en fil av 300K poster i ca 5 sekunder.

Svarte 28/04/2017 kl. 21:31
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more