2017-11-17 1 views
0

그래서 난 내 스크립트에서이 루프를 가지고 :속도 최대 PowerShell 스크립트 (호출-SQLCMD 및 Word 개체)

foreach ($candID in Get-Content $candList) 
{ 
    $candID = $candID -replace '\s','' 
    $candID 

    $templateDir = Get-ChildItem ($ScriptPath + "Templates\Resumes\") | Get-Random -Count 1 
    $templateFile = $templateDir 
    $templateDir = ($ScriptPath + "Templates\Resumes\" + $templateDir) 

    $lname = Invoke-Sqlcmd -Query "SELECT LEFT(personFirstName, 1) FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 

    $firstname = Invoke-Sqlcmd -Query "SELECT personFirstName FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $surname = Invoke-Sqlcmd -Query "SELECT personSurname FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $Address1 = Invoke-Sqlcmd -Query "SELECT CandidateAddress FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $City  = Invoke-Sqlcmd -Query "SELECT CandidateCity FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $Postcode = Invoke-Sqlcmd -Query "SELECT CandidatePostcode FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $Mobile = Invoke-Sqlcmd -Query "SELECT personMobileTelephone FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $State  = Invoke-Sqlcmd -Query "SELECT CandidateState FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 

    $firstname = $firstname.ItemArray[0] 
    $surname = $surname.ItemArray[0] 
    $Address1 = $Address1.ItemArray[0] 
    $City  = $City.ItemArray[0] 
    $Postcode = $Postcode.ItemArray[0] 
    $Mobile = $Mobile.ItemArray[0] 
    $State  = $State.ItemArray[0] 
    $lName  = $lName.ItemArray[0] 

    cls 

    ### Loop Visual 
    Write-Host "" 
    Write-Host "Generating resumes" -ForegroundColor Cyan 
    Write-Host " ---------------------------------------------------------------------------------------------------- " 
    Write-Host "" 
    Write-Host "" 
    Write-Host "Using resume template: $templateFile" -foregroundColor GREEN 
    Write-Host "" 
    Write-Host "Data:" 

    Write-Host " Firstname = $firstname" 
    Write-Host " surname  = $surname" 
    Write-Host " Address1 = $Address1" 
    Write-Host " City  = $City"  
    Write-Host " Postcode = $Postcode" 
    Write-Host " Mobile  = $Mobile" 
    Write-Host " State  = $State"  

    ### End Loop Visual 

    $filename = ($firstname + " " + $surname + " - " + $candID + ".doc") 
    $filename2 = ($firstname + " " + $surname + " - " + $candID + ".txt") 

    $saveAs = ($scriptPath + "Documents\Original Resumes\" + $lName + "\" + $filename) 
    $saveAs2 = ($scriptPath + "Documents\Original Resumes\" + $lName + "\" + $filename2) 

    $objWord = New-Object -comobject Word.Application 
    $doc=$objWord.documents.Add($templateDir) 
    $objWord.Visible = $false 
    $doc.Bookmarks.Item("Address1").Range.Text = $Address1 
    $doc.Bookmarks.Item("firstName").Range.Text = $firstname 
    $doc.Bookmarks.Item("surName").Range.Text = $surname 
    $doc.Bookmarks.Item("City").Range.Text = $City 
    $doc.Bookmarks.Item("Postcode").Range.Text = $Postcode 
    $doc.Bookmarks.Item("Mobile").Range.Text = $Mobile 
    $doc.Bookmarks.Item("State").Range.Text = $State 
    $doc.SaveAs([REF]$saveAs) 
    $doc.Close() 

    $doc2=$objWord.documents.Add($saveAs) 
    $doc2.SaveAs([REF]$saveAs2, [REF] 2) 

    $objWord.Quit() 
} 

기본적으로, 내가 만드는 오전 스푸핑 워드 템플릿을 사용하여 데이터베이스에서 레코드를 다시 시작합니다. 스크립트는 작동하지만 5 초마다 2 ~ 3 개의 이력서 만 작성합니다. 전체 데이터베이스 (1 백만개의 스푸핑 된 레코드)를 채워야하기 때문에 조금 문제가됩니다.

플러스, 어떤 시점에서 템플릿을 임의로 만들지 않으므로 시간이 오래 걸리기 때문에 사람의 산업에 음식을 제공하고 각 이력서에 더 많은 데이터를 추가 할 수 있습니다 (기술 , 참조 등).

조금 더 빠르게 할 수있는 방법이 있습니까?

+2

1 일이 하나 개의 문장에 SQL을 감소하는 것입니다 : 샘플 데이터를 가지고 또는 $candList에서 해당 파일이 정말로에 포함 된 내용을 알지 못하고,이 같은 스크립트 뭔가의 위쪽 절반을 할 수

. 하나의 쿼리에서 각 값을 쿼리 할 필요가 없습니다. 그것을 하나로 가져 가라. '$ objWord' 만 써야합니다. 루프 외부에서 한 번 초기화하십시오. 밖에 나가십시오. 당신이 그것을 피할 수있는 경우 콘솔에 정보를 쓰는 데 시간을 낭비하지 마십시오. 천천히. 로깅을 원하면 파일에 넣으십시오. – Matt

+0

좋습니다, 감사합니다! 그러면 각 값은 항목 배열에서 다른 숫자가됩니까? 그래서 성은 sqlResult.ItemArray [1]이 될 것입니까? –

+0

모든 변경 사항을 적용하면 5 초당 7 - 8이됩니다. 이는 상당한 증가입니다. 감사합니다. 모든 이력서를 작성하는 데 8 일이 걸리 겠지만 20보다 우수합니다. –

답변

0

첫 번째 단계는 PowerShell 3.0 이상에서이 스크립트를 실행하는지 확인하는 것입니다. 사무실 COM 개체는 PowerShell 2.0에서 성능이 좋지 않은 것으로 알려져 있으며 스크립트를 편집하지 않으면 더 빠르게 실행될 수 있습니다.

스크립트 전체적으로 SQL Server에서 데이터를 검색하는 부분을 조정할 것입니다. 댓글을 달았을 때 이것을 한 번의 호출로 만들 수 있습니다.

$candData = Get-Content $candList -Raw | ForEach-Object {$_ -replace '\s',''} 

$qry = " 
    SELECT personFistName, 
     LEFT(personFirstName, 1) AS personLastName, 
     personSurname, 
     CandidateAddress, 
     CandidateCity, 
     CandidatePostcode, 
     personMobileTelephone, 
     CandidateState 
    FROM tblCandidate 
    WHERE personID IN ($($candData -split ',')); 
" 
$templateDir = Get-ChildItem ($ScriptPath + "Templates\Resumes\") | Get-Random -Count 1 
$templateFile = $templateDir 
$templateDir = ($ScriptPath + "Templates\Resumes\" + $templateDir) 

$data = Invoke-SqlCmd -ServerInstance $ServerAddress -Database $DatabaseName -Query $qry 

foreach ($row in $data) { 
    $lname = $row.personLastName 
    $firstname = $row.personFirstName 
    $surname = $row.personSurname 
    $Address1 = $row.CandidateAddress 
    $City  = $row.CandidateCity 
    $Postcode = $row.CandidatePostcode 
    $Mobile = $row.personMobileTelephone 
    $State  = $row.CandidateState 
+0

나는 약간 혼란 스럽습니다. 죄송합니다. 저는 PowerShell을 처음 사용합니다. 이 작업은 데이터베이스의 모든 행을 객체에 저장하는 것입니까? $ 1000000 행의 일부 문제가 $ 데이터에 저장되는 원인이되지 않습니까? –

+0

그냥 시도하고 작동하지 않았다. candList 파일은 개행 문자로 구분 된 ID 목록 일뿐입니다. Microsoft.SqlServer.Management.PowerShell.SqlPowerShellSqlExecutionException : '1330002'근처의 구문이 잘못되었습니다. ---> System.Data.SqlClient.SqlException : '1330002'근처의 구문이 잘못되었습니다. –