簡體   English   中英

將 PowerShell 腳本從調用更改為批量復制

[英]Change PowerShell script from Invoke to Bulk Copy

我已經使用下面的代碼一段時間了,主要是作為一個測試來了解它。 我現在真正想做的是通過使用批量復制來提高速度。

代碼從服務器上的文本文件中保存的一系列實例中獲取數據庫和表信息,然后通過調用將收集的數據添加到表中。

問題在於,如果可能的話,它會一次發送每個數據庫和每個表的數據。

我查看了許多提供這方面信息的網站/博客,但它們似乎都不是我所需要的。

$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$today = Get-Date
$srvlist = @(Get-Content "c:\scripts\tablegrowth.TXT")
foreach ($server in $srvlist) {
    $srv = New-Object "Microsoft.SqlServer.Management.SMO.Server" $server
    $dbs = $srv.Databases
    foreach ($db in $dbs) {
        if ($db.IsAccessible) {
            $name1 = $db.name
            $size1 = $db.size
            $dbspace1 = $db.DataSpaceUsage/1KB
            $dbindexsp1 = $db.IndexSpaceUsage/1KB
            $dbspaceavail1 = $db.SpaceAvailable/1KB
            #Write-Host "dbname=" $name1 $size1 $dbspace1 $dbindexsp1 $dbspaceavail1 $db.IsAccessible
            switch ($name1) {
                'master' {}
                'msdb' {}
                'model'  {}
                'SSISDB'  {}
                'SSRSData'  {}
                'Northwind' {}
                'tempdb' {}
                default {
                    Invoke-Sqlcmd -ServerInstance "******" -Database "DBAMonitoring" -Query "INSERT INTO is_sql_databases VALUES ('$server','$name1','$today',$dbspace1,$dbspaceavail1,$dbindexsp1) "
                    foreach ( $tbl in $db.tables) {
                        $tname1    = $tbl.Name
                        $tindexsp1 = $tbl.IndexSpaceUsed/1KB
                        $trows1    = $tbl.RowCount
                        $tspace1   = $tbl.DataSpaceUsed/1KB
                        #Write-Host "tbl name=" $tname1 $tindexsp1 $trows $tspace1
                        if ($trows1 -gt 500) {
                            Invoke-Sqlcmd -ServerInstance "****" -Database "DBAMonitoring" -    Query "INSERT INTO is_sql_tables VALUES ('$server','$name1','$tname1','$today',$trows1,$tspace1,$tindexsp1) "
                        } ####end RowCount > 0
                    } #####end Row loop
                } ###### end Default
            } #####end switch
        }  #####end IsAccessible
    }  #####end database loop
} ###end server loop

$Stopwatch.Stop()
$Stopwatch.Elapsed.TotalSeconds
$Stopwatch.Elapsed.TotalMinutes

一種方法是將行加載到 DataTable 中,並在腳本中直接使用 .NET SqlBulkCopy 進行批量插入。 只需更改以下示例中的 DataTable 列名和數據類型以匹配您的實際表。

$dt = New-Object System.Data.DataTable;
[void]($dt.Columns.Add("server_name", [System.Type]::GetType("System.String")).MaxLength = 128)
[void]($dt.Columns.Add("name1", [System.Type]::GetType("System.String")).MaxLength = 128)
[void]($dt.Columns.Add("tname1", [System.Type]::GetType("System.String")).MaxLength = 128)
[void]($dt.Columns.Add("today", [System.Type]::GetType("System.DateTime")))
[void]($dt.Columns.Add("trows1", [System.Type]::GetType("System.Int64")))
[void]($dt.Columns.Add("tspace1", [System.Type]::GetType("System.Int64")))
[void]($dt.Columns.Add("tindexsp1", [System.Type]::GetType("System.Int64")))

$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$today = Get-Date
$srvlist = @(Get-Content "c:\scripts\tablegrowth.TXT")
foreach ($server in $srvlist) {
    $srv = New-Object "Microsoft.SqlServer.Management.SMO.Server" $server
    $dbs = $srv.Databases
    foreach ($db in $dbs) {
        if ($db.IsAccessible) {
            $name1 = $db.name
            $size1 = $db.size
            $dbspace1 = $db.DataSpaceUsage/1KB
            $dbindexsp1 = $db.IndexSpaceUsage/1KB
            $dbspaceavail1 = $db.SpaceAvailable/1KB
            #Write-Host "dbname=" $name1 $size1 $dbspace1 $dbindexsp1 $dbspaceavail1 $db.IsAccessible
            switch ($name1) {
                'master' {}
                'msdb' {}
                'model'  {}
                'SSISDB'  {}
                'SSRSData'  {}
                'Northwind' {}
                'tempdb' {}
                default {
                    # Invoke-Sqlcmd -ServerInstance "******" -Database "DBAMonitoring" -Query "INSERT INTO is_sql_databases VALUES ('$server','$name1','$today',$dbspace1,$dbspaceavail1,$dbindexsp1) "
                    foreach ( $tbl in $db.tables) {
                        $tname1    = $tbl.Name
                        $tindexsp1 = $tbl.IndexSpaceUsed/1KB
                        $trows1    = $tbl.RowCount
                        $tspace1   = $tbl.DataSpaceUsed/1KB
                        #Write-Host "tbl name=" $tname1 $tindexsp1 $trows $tspace1
                        if ($trows1 -gt 500) {
                            # Invoke-Sqlcmd -ServerInstance "." -Database "tempdb" -Query "INSERT INTO is_sql_tables VALUES ('$server','$name1','$tname1','$today',$trows1,$tspace1,$tindexsp1) "
                            $row = $dt.NewRow()
                            $dt.Rows.Add($row)
                            $row["server_name"] = $server
                            $row["name1"] = $name1
                            $row["tname1"] = $tname1
                            $row["today"] = $today
                            $row["trows1"] = $trows1
                            $row["tindexsp1"] = $tindexsp1
                        } ####end RowCount > 0
                    } #####end Row loop
                } ###### end Default
            } #####end switch
        }  #####end IsAccessible
    }  #####end database loop
} ###end server loop

$bcp = New-Object System.Data.SqlClient.SqlBulkCopy("Data Source=******;Integrated Security=SSPI;Initial Catalog=DBAMonitoring ")
$bcp.DestinationTableName = "dbo.is_sql_tables"
$bcp.WriteToServer($dt);

$Stopwatch.Stop()
$Stopwatch.Elapsed.TotalSeconds
$Stopwatch.Elapsed.TotalMinutes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM