2015-06-03 2 views
0

Я написал сценарий для чтения данных из csv в таблицу, а затем в массивную копию таблицы sql. В то время я не понимал, что мне, возможно, придется писать по существующим строкам, и объемная копия не поддерживает это. Я просто не знаю, как изменить скрипт для записи по существующей строке, если данные уже существуют. Вот что у меня есть. Как бы я обновил данные в таблице, используя csv. Любая помощь будет оценена. благодаря!Bulkcopy to sql table, если существует строка существует обновление

$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 
    "" 
    "" 
    "" 
    }}} 
+0

Wich dbms продукт используется? – jarlh

+1

@jarlh: По connectionString, похоже, что это SQL Server 2008. – sstan

+0

Я подключаюсь к sql 2008 – user2402045

ответ

0

При загрузке файла CSV для временной таблицы SQL, то вы можете использовать совмещенный оператор для вставки/обновления записей в итоговую таблицу SQL.

Дополнительную информацию о команде MERGE можно найти here.

+0

Спасибо, я попробую это. – user2402045

Смежные вопросы