c# - Load a DataTable from a SQLDataReader in batches using Powershell -


i need load datatable sqldatareader in batches. sqldatareader return millions of records, , datatable load() method exhaust available memory.

here current code:

[cmdletbinding( defaultparametersetname = 'instance',                     supportsshouldprocess = $true,                     confirmimpact = 'high' )] param (    [string] $srcserver     = "mysqlserver,12345",    [string] $srcdatabase   = "sourcedb",    [string] $srctable      = "dbo.sourcetable",    [string] $srcquery      = "select top 100 hashbytes('sha',stay_number) stay_number_h, * $srctable",    [string] $tgtserver,    [string] $tgtdatabase   = "targetdb",    [string] $tgttable      = "tmp.targettable",    [switch] $truncate      = $true )  function connectionstring([string] $servername, [string] $dbname) {    "data source=$servername;initial catalog=$dbname;integrated security=true;connection timeout=30" }  ########## main body ############ write-host "starting..."  if ($tgtserver.length –eq 0) {    $tgtserver = $srcserver }  if ($tgtdatabase.length –eq 0) {    $tgtdatabase = $srcdatabase }  if ($tgttable.length –eq 0) {    $tgttable = $srctable }  if ($truncate) {    write-host "truncating $tgttable"    $truncatesql = "truncate table " + $tgttable    sqlcmd -s $tgtserver -d $tgtdatabase -q $truncatesql }  $srcconnstr = connectionstring $srcserver $srcdatabase $srcconn  = new-object system.data.sqlclient.sqlconnection($srcconnstr) $cmdtext = $srcquery $sqlcommand = new-object system.data.sqlclient.sqlcommand($cmdtext, $srcconn) $srcconn.open() [system.data.sqlclient.sqldatareader] $sqlreader = $sqlcommand.executereader()  # can convert sqlreader datatable? $dtschema = $sqlreader.getschematable() $dt = new-object system.data.datatable  if ($dtschema -ne $null) {     foreach ($drow in $dtschema.rows)     {         $columnname = $drow["columnname"]         $column = new-object system.data.datacolumn($columnname, $drow["datatype"])         $column.unique = $drow["isunique"]         $column.allowdbnull = $drow["allowdbnull"]         $column.autoincrement = $drow["isautoincrement"]         $dt.columns.add($column)     } }  write-host "now loading datatable" ($i=0;$i -le 10; $i++) {    $i    $null = $dt.loaddatarow($sqlreader,$true) } write-host "datatable filled, how long , check memory consumption!"  sleep 30  $datatable.clear()  write-host "finished" 

related links:

csv sql server:
https://gallery.technet.microsoft.com/scriptcenter/import-large-csvs-into-sql-216223d9 https://gallery.technet.microsoft.com/scriptcenter/import-large-csvs-into-sql-fa339046

sql server sql server:
https://blogs.technet.microsoft.com/heyscriptingguy/2011/05/06/use-powershell-to-copy-a-table-between-two-sql-server-instances/ https://newsqlblog.com/2011/08/12/moving-data-between-sql-servers-with-powershell/ https://raw.githubusercontent.com/ramblingcookiemonster/powershell/master/invoke-sqlbulkcopy.ps1

ideally final solution support both ss , external files import (actually can realized datatable)

not powershell, how process batch db:

it requires class fields match table, , processes data in whatever bath size using system.reflection:

public static void sql_reader_to_type(type t, sqldatareader r)     {          list<object> ret = new list<object>();         while (r.read())         {              fieldinfo[] f = t.getfields();             object o = activator.createinstance(t);             (int = 0; < f.length; i++)             {                 string thistype = f[i].fieldtype.tostring();                 switch (thistype)                 {                     case "system.string":                          f[i].setvalue(o, convert.tostring(r[f[i].name]));                         break;                     case "system.int16":                         f[i].setvalue(o, convert.toint16(r[f[i].name]));                         break;                     case "system.int32":                         f[i].setvalue(o, convert.toint32(r[f[i].name]));                         break;                     case "system.int64":                         f[i].setvalue(o, convert.toint64(r[f[i].name]));                         break;                     case "system.double":                         // console.writeline("converting " + f[i].name + " double");                         double th;                         if (r[f[i].name] == null)                         {                             th = 0;                         }                         else                         {                             if (r[f[i].name].gettype() == typeof(dbnull))                             {                                 th = 0;                             }                             else                             {                                 th = convert.todouble(r[f[i].name]);                             }                         }                          f[i].setvalue(o, th);                          break;                     case "system.boolean":                         f[i].setvalue(o, convert.toint32(r[f[i].name]) == 1 ? true : false);                         break;                     case "system.datetime":                         f[i].setvalue(o, convert.todatetime(r[f[i].name]));                         break;                     default:                         throw new exception("missed data type in sql select in getclassmembers class line 73");                  }             }             ret.add(o);             if (ret.count == 50000)             {                 //process data                 ret.clear();             }          }         if (ret.count > 0)         {             //processdata         }       }  create table (firstname varchar(25), lastname varchar(50), birthday date)  class person{public string firstname; public string lastname; public datetime birthday}  sql_reader_to_type(typeof(person), com.executereader()); 

Comments

Popular posts from this blog

mysql - Dreamhost PyCharm Django Python 3 Launching a Site -

java - Sending SMS with SMSLib and Web Services -

java - How to resolve The method toString() in the type Object is not applicable for the arguments (InputStream) -