2016-09-21 39 views
0

我試圖創建一個腳本,它使用Write-DataTable函數(源代碼here)將多個數據庫服務器的數據導入到一箇中央數據存儲庫中。如果目標表(RPRMBSDEVDB81.dba_rep..DBBakSizes)爲空,但是,如果表中有數據發生,那麼我提出的腳本會工作。寫入SQL Server表時寫入數據表的行爲不一致

我在做什麼:

  1. 我通過SQL服務器管理工​​作室刪除一切從目標表中。
  2. 我運行PowerShell腳本,它運行成功,數據在表中結束。
  3. 我通過SSMS爲目標表中的一臺服務器刪除數據。
  4. 我再次運行PowerShell腳本,驗證我的數據表中有唯一數據,並且出錯(請參閱我的腳本下的完整錯誤)。

我的腳本:

#Clear screen (for testing) 
Clear-Host 

#SQLCMD timeout parameter 
$QueryTimeout = 120 

#Get list of servers to import data from 
$sql_serverlist = " 
SELECT sl.HostName 
    ,sl.ServerName + '.' + sl.Domain AS ServerName 
    ,ISNULL(MAX(bs.ReportDate),'1/1/1980') AS ReportDate 
FROM dbo.ServerList sl 
    LEFT OUTER JOIN dbo.DBBakSizes bs ON bs.ServerName = sl.HostName 
WHERE sl.Import = 1 
AND sl.Active = 1 
GROUP BY sl.HostName 
    ,sl.ServerName + '.' + sl.Domain; 
" 
$servers = Invoke-Sqlcmd -ServerInstance RPRMBSDEVDB81 -Database dba_rep -Query $sql_serverlist 

#Define path to Write-DataTable module 
$Location = "C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\Modules\Write-DataTable" 
#Load Write-DataTable module 
Import-Module $Location\Write-DataTable.psm1 

#Setup DataTable 
$dt = New-Object Data.DataTable 
$col1 = New-Object Data.DataColumn ServerName,([string]) 
$col2 = New-Object Data.DataColumn DatabaseName,([string]) 
$col3 = New-Object Data.DataColumn BackupType,([string]) 
$col4 = New-Object Data.DataColumn UsedCompression,([int]) 
$col5 = New-Object Data.DataColumn UsedChecksum,([int]) 
$col6 = New-Object Data.DataColumn MostRecentFull_Date,([datetime]) 
$col7 = New-Object Data.DataColumn MostRecentFull_Sec,([int]) 
$col8 = New-Object Data.DataColumn MostRecentFull_MB,([int]) 
$col9 = New-Object Data.DataColumn MostRecentOther,([string]) 
$col10 = New-Object Data.DataColumn MostRecentOther_Date,([datetime]) 
$col11 = New-Object Data.DataColumn MostRecentOther_Sec,([int]) 
$col12 = New-Object Data.DataColumn MostRecentOther_MB,([int]) 
$col13 = New-Object Data.DataColumn ReportDate,([datetime]) 
$dt.columns.add($col1) 
$dt.columns.add($col2) 
$dt.columns.add($col3) 
$dt.columns.add($col4) 
$dt.columns.add($col5) 
$dt.columns.add($col6) 
$dt.columns.add($col7) 
$dt.columns.add($col8) 
$dt.columns.add($col9) 
$dt.columns.add($col10) 
$dt.columns.add($col11) 
$dt.columns.add($col12) 
$dt.columns.add($col13) 

#Loop through servers and pull in bak file data 
foreach ($server in $servers) 
{ 
    #Retrieve ServerName and MAX(ReportDate) from array 
    $hostname = $server[0] 
    $servername = $server[1] 
    $reportdate = $server[2].ToString() 

    #Build SQL to retrieve records for import 
    $sql_bakdata = " 
    SELECT '$hostname' AS ServerName 
     ,DatabaseName 
     ,BackupType 
     ,UsedCompression 
     ,UsedChecksum 
     ,MostRecentFull_Date 
     ,MostRecentFull_Sec 
     ,MostRecentFull_MB 
     ,MostRecentOther 
     ,MostRecentOther_Date 
     ,MostRecentOther_Sec 
     ,MostRecentOther_MB 
     ,ReportDate 
    FROM rp_util.dbo.DBBakSizes 
    WHERE CAST(ReportDate AS SMALLDATETIME) > '$reportdate'; 
    " 

    #Run SQL and capture results in array 
    $dt += Invoke-Sqlcmd -ServerInstance $servername -Query $sql_bakdata -QueryTimeout $QueryTimeout 
} 

#Load data 
Write-DataTable -ServerInstance "RPRMBSDEVDB81" -Database "dba_rep" -TableName "DBBakSizes" -Data $dt 

錯誤:

Write-DataTable : System.Management.Automation.MethodInvocationException: 
Exception calling "WriteToServer" with "1" argument(s): "Object reference not 
set to an instance of an object." ---> System.NullReferenceException: Object 
reference not set to an instance of an object. 
    at System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataRow[] rows) 
    at WriteToServer(Object , Object[]) 
    at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments) 
    --- End of inner exception stack trace --- 
    at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments) 
    at System.Management.Automation.ParserOps.CallMethod(Token token, Object target, String methodName, Object[] paramArray, Boolean callStatic, Object valueToSet) 
    at System.Management.Automation.MethodCallNode.InvokeMethod(Object target, Object[] arguments, Object value) 
    at System.Management.Automation.MethodCallNode.Execute(Array input, Pipe outputPipe, ExecutionContext context) 
    at System.Management.Automation.ParseTreeNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context) 
    at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context).Message 
At line:2 char:16 
+ Write-DataTable <<<< -ServerInstance "RPRMBSDEVDB81" -Database "dba_rep" -TableName "DBBakSizes" -Data $dt 
    + CategoryInfo   : NotSpecified: (:) [Write-Error], WriteErrorException 
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Write-DataTable
+0

'寫DataTable'來自[這裏](https://gallery.technet.microsoft.com/scriptcenter/2fdeaf8d-b164-411c-9483-99413d6053ae)? – Matt

+0

對不起,不包括鏈接,但是,這是我從中得到的。 –

回答

0

放棄了寫數據表。我的腳本現在循環訪問DataTable並通過令人興奮的行插入行。

#Load data 
#Write-DataTable -ServerInstance "RPRMBSDEVDB81" -Database "dba_rep" -TableName "DBBakSizes" -Data $dt 
$SqlConnection = new-object System.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$DBServer; Database=$DBName; Integrated Security=SSPI;" 
$SqlConnection.Open() 
$SqlCommand = new-object System.Data.SqlClient.SqlCommand 
$SqlCommand.Connection = $SqlConnection 

foreach ($dtrow in $dt) 
{ 
    If ($dtrow.ServerName) #Skip NULL/empty records 
    { 
    $SqlInsert = "INSERT dbo.DBBakSizes VALUES('$($dtrow.ServerName)','$($dtrow.DatabaseName)','$($dtrow.BackupType)',$($dtrow.UsedCompression),$($dtrow.UsedChecksum),'$($dtrow.MostRecentFull_Date)',$($dtrow.MostRecentFull_Sec),$($dtrow.MostRecentFull_MB),'$($dtrow.MostRecentOther)','$($dtrow.MostRecentOther_Date)',$($dtrow.MostRecentOther_Sec),$($dtrow.MostRecentOther_MB),'$($dtrow.ReportDate)')" 
    $SqlCommand.CommandText = $SqlInsert 
    $SqlCommand.ExecuteNonQuery() 
    } 
} 

$SqlConnection.Close()