我有一個按需運行的powershell進程,它通過Web服務調用從應用程序收集所有「請求歷史記錄」日誌。結果請求被轉換爲對象,並使NoteProperty值(屬性值對)每週結束於大型列表數組(通常爲1400個項目)。正確使用數據表
我想要做的就是將所有這些請求存儲爲歷史目的,以便應用程序不會自行清除它們。因此,我在一個數據庫上創建了一個簡單的表格,該表格存儲了每個請求的所有屬性值對,這些值在我新創建的數據庫中不存在。
然後,我將powershell腳本中的OleDB連接設置爲MSSQL服務器,並從表中選擇所有記錄以填充DataTable(我對OleDB或DataTables不太好)。之後,我循環訪問列表數組中的每個項目以驗證它在DataTable中不存在。對於每個不存在的記錄,我使用屬性 - 值對在DataTable中添加一個新行。從那裏我假設命令生成器幫助使用Insert語句,因此如果它爲空或空白,甚至不寫查詢,我不必檢查每個屬性值。最後,我用新添加的DataTable「更新」OleDBAdapter。
雖然這個過程起作用,但我意識到它正在從數據庫中拉出所有數據,然後與我的列表數組進行比較並重新提交新添加的記錄。數據庫越大,需要的時間越長。無論如何,無需編寫任何SQL語句就可以快速高效地執行此操作。我喜歡CommandBuilder如何爲DataTables工作。
下面是調用以更新數據庫中的所有功能的「請求記錄」對象已經進賬
function UpdateDatabase([Parameter(Mandatory=$true)] $allRequests)
{
$objOleDbConnection = New-Object "System.Data.OleDb.OleDbConnection"
$objOleDbCommand = New-Object "System.Data.OleDb.OleDbCommand"
$objOleDbAdapter = New-Object "System.Data.OleDb.OleDbDataAdapter"
$objDataTable = New-Object "System.Data.DataTable"
$objOleDbConnection.ConnectionString = "Provider=SQLNCLI10;Server=SERVER;Database=DB1;Trusted_Connection=yes;"
$objOleDbConnection.Open()
$objOleDbCommand.Connection = $objOleDbConnection
$objOleDbCommand.CommandText = "SELECT * FROM dbo.RequestLog"
##set the Adapter object and command builder
$objOleDbAdapter.SelectCommand = $objOleDbCommand
$objOleDbCommandBuilder = New-Object "System.Data.OleDb.OleDbCommandBuilder"
$objOleDbCommandBuilder.DataAdapter = $objOleDbAdapter
##fill the objDataTable object with the results
[void] $objOleDbAdapter.Fill($objDataTable)
[void] $objOleDbAdapter.FillSchema($objDataTable,[System.Data.SchemaType]::Source)
#store all the primary keys in a list for kicking out dups
$sql_id = @()
$objDataTable.Rows | foreach { $sql_id += $_.PKID}
#####
#loop through all the requests
trap {
"Error: $($i)"
}
$i = 0
$total = $allRequests.count
foreach ($request in $allRequests)
{
$i++
write-progress -activity "Filling DataTable" -status "% Complete: $($i/$total*100)" -PercentComplete ($i/$total*100)
#check to see if entry already exists in our table (by primary key)
if (!($sql_id -contains $request.PKID.Value))
{
#shouldn't have to do this but i noticed sometimes requests are duplicate in the list? (probably restarted the script and caught some old requests
$sql_id += $request.PKID.Value
$row = $objDataTable.Rows.Add($request.PKID.Value)
#go through all the attributes from the request and add them to the table
$list = get-member -in $request | Where-Object { $_.MemberType -eq "NoteProperty" }
foreach ($attr in $list)
{
if ($request.($attr.name) -ne $null)
{
$row.($attr.name) = $request.($attr.name)
}
}
} else {
#PKID already in DB
}
}
#update the database with our new records
$objOleDbAdapter.Update($objDataTable)
## close the connection
$objOleDbConnection.Close()
}
感謝@chad,我會考慮使用表值參數,雖然我不知道我是否有權創建存儲過程 – 2012-04-30 21:05:01