Bulkcopy到sql表,如果行存在更新

时间:2015-06-03 13:48:55

标签: sql sql-server insert duplicates

我编写了一个脚本来将csv中的数据读入表中,然后将其批量复制到sql表中。当时我没有意识到我可能需要写入现有的行,而bulkcopy不支持这一点。我只是不确定如果数据已存在,如何修改脚本以写入现有行。这就是我所拥有的。如何使用csv更新表中的数据任何帮助将不胜感激。谢谢!

$CurrentDate = Get-Date
$CurrentDate = $CurrentDate.ToString('MM-dd-yyyy_hh-mm-ss')

 # Database variables
$sqlserver = "db-sqlent1-prd\sql2008"
$database = "Employees"
$table = "dbo.tblPersonal"

# CSV variables;  
$csvfile = $return[2]
$csvdelimiter = ","
$firstrowcolumnnames = $true
$empidcolname = 'SSN'
$empidvalue = $return[1]


$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=db-ent3-dev\sql2008;Database=Employees;Integrated Security=True"
$SqlConnection.Open()
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand

$SqlCmd.CommandText =

"select * from tblpersonal where SSN='0'"


$SqlCmd.Connection = $SqlConnection
$OpenSSN = $SqlCmd.ExecuteScalar()
$SqlConnection.Close()



if($OpenSSN){ overwrite    data }else{

Try
 {

$elapsed = [System.Diagnostics.Stopwatch]::StartNew()


$batchsize = 100000

# Build the sqlbulkcopy connection, and set the timeout to infinite
$connectionstring = "Data Source=$sqlserver;Integrated Security=true;Initial Catalog=$database;"

$bulkcopy = new-object ("Data.SqlClient.Sqlbulkcopy") $connectionstring
$bulkcopy.DestinationTableName = $table
$bulkcopy.bulkcopyTimeout = 0
$bulkcopy.batchsize = $batchsize



#$bulkcopy.EnableStreaming = 1

# Create the datatable, and autogenerate the columns.
$datatable = New-Object "System.Data.DataTable"

# Open the text file from disk
$reader = new-object System.IO.StreamReader($csvfile)
$line = $reader.ReadLine()
$columns =  $line.Split($csvdelimiter)

    if ($firstrowcolumnnames -eq $false) {
        foreach ($column in $columns) {
            $null = $datatable.Columns.Add()
            }
        # start reader over
        $reader.DiscardBufferedData();  
        $reader.BaseStream.Position = 0;
        }
    else {
        foreach ($column in $columns) {
            $null = $datatable.Columns.Add($column)
        } $null = $datatable.Columns.Add($empidcolname)
    }



$ColumnMap1 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping("$empidcolname",'SSN')
$ColumnMap2 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('LastName', 'LastName')
$ColumnMap3 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('FirstName','FirstName')
$ColumnMap4 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('PreferredName','PreferredName')
$ColumnMap5 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('WorkPhone','WorkPhone')
$ColumnMap6 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Email','Email')
$ColumnMap7 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('EmpType','EmpType')
$ColumnMap8 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('HireDate', 'HireDate')
$ColumnMap9 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('ACID','ACID')
$ColumnMap10 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('OPID','OPID')
$ColumnMap11 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Floor','Floor')
$ColumnMap12 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Department','Department')
$ColumnMap13 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Division','Division')
$ColumnMap14 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('JobCode','JobCode')

$BulkCopy.ColumnMappings.Add($ColumnMap1)
$BulkCopy.ColumnMappings.Add($ColumnMap2)
$BulkCopy.ColumnMappings.Add($ColumnMap3)
$BulkCopy.ColumnMappings.Add($ColumnMap4)
$BulkCopy.ColumnMappings.Add($ColumnMap5)
$BulkCopy.ColumnMappings.Add($ColumnMap6)
$BulkCopy.ColumnMappings.Add($ColumnMap7)
$BulkCopy.ColumnMappings.Add($ColumnMap8)
$BulkCopy.ColumnMappings.Add($ColumnMap9)
$BulkCopy.ColumnMappings.Add($ColumnMap10)
$BulkCopy.ColumnMappings.Add($ColumnMap11)
$BulkCopy.ColumnMappings.Add($ColumnMap12)
$BulkCopy.ColumnMappings.Add($ColumnMap13)
$BulkCopy.ColumnMappings.Add($ColumnMap14)


 # Read in the data, line by line
    while (($line = $reader.ReadLine()) -ne $null)  {
        $row = $datatable.NewRow()
        $row.itemarray = $line.Split($csvdelimiter)
        $datatable.Rows.Add($row)   
        $row[$empidcolname] = $empidvalue
        # Once you reach your batch size, write to the db,  
        # then clear the datatable from memory
        $i++; if (($i % $batchsize) -eq 0) {
        $bulkcopy.WriteToServer($datatable)
        $datatable.Clear()
        }
    }

# Close the CSV file
$reader.Close()

    # Add in all the remaining rows since the last clear
    if($datatable.Rows.Count -gt 0) {
        $bulkcopy.WriteToServer($datatable)
        $datatable.Clear()
    }

# Garbage collector
[System.GC]::Collect()
 }
 Catch
 {
""
""
""
""
 write-host "Caught an exception while trying to write to Tbl.Personal:" -ForegroundColor Red
    write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red
    write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red
       write-output "$($_.Exception.Message)" | out-file "c:\temp\CIDB_insert $CurrentDate.log" -append
   ""
   ""
   Write-host "tbl.personal insert failed!" -ForegroundColor Red
  ""
  ""
  ""
    }}}

1 个答案:

答案 0 :(得分:0)

如果将CSV文件加载到临时SQL表,则可以使用MERGE语句将记录插入/更新到最终的SQL表。

可以找到有关MERGE命令的更多信息here