Powershell передает переменную для работы с циклом запроса SQL и В предложении

#powershell #variables #parameter-passing #sqlclient

#powershell #переменные #передача параметров #sqlclient

Вопрос:

Что мне нравится делать, так это передавать переменную $ sContractNumbers в приведенный ниже цикл, который, по сути, объединяет два файла CSV на основе запросов SQL.

Я использую приведенный ниже блок для получения значения из электронной таблицы Excel. Что-то, что будет обновлено другим пользователем. Ячейка всегда будет статической, но размер данных в ячейке изменится, поэтому я должен использовать предложение IN.

Значение моей переменной выглядит следующим образом.

$sContractNumbers = ‘abc123’, ‘abc456’, ‘abc789’, ‘abc112’, ‘abc345’

 
    $xl = New-Object -COM "Excel.Application"
    $xl.Visible = $true
    $wb = $xl.Workbooks.Open("C:DevBlahManualContracts.xlsx")
    $ws = $wb.Sheets.Item(1)
    #Looking up a value in one column and assigning the corresponding value from another column to a variable could be done like this:
    
    for ($i = 0; $i -le 1; $i  ) {
      if ( $ws.Cells.Item(1, 2).Text -eq $ColumnHeader ) {
        $i = $i  ;
        $sContractNumbers = $ws.Cells.Item(2, 2).Value
        #$sContractNumber
        break
      }
    }
    
    $wb.Close()
    $xl.Quit()
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)
    
    $sContractNumbers

  

До добавления этой части я просто копировал и вставлял свой список контрактов в оба запроса.

В настоящее время ошибка, которую я получаю, заключается в следующем. Я не верю, что цикл обрабатывает переменную. Я пытался использовать AddWithValue, но я не думаю, что размещаю его правильно, поэтому его нет в списке. Довольно новичок в powershell, но немного знаком с T-SQL. Я думаю, что это простой вопрос, но я не могу полностью понять, что мне нужно исправить, так как я новичок. Будьте осторожны…

     $DetailContent[1] = "{0}`r`n{1}" -f $HeadeDetail, $DetailContent[1]
         |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         | Cannot index into a null array.

  
 
    Function Run-Query
    {
        param([string[]]$queries,[string[]]$sheetnames)
        Begin
        {
            $SQLServer = 'server'
            $Database = 'warehouse'
            $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
            $SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"
            $FileNameDate = Get-Date -f 'yyyyMMdd'
        }#End Begin
        Process
        {
            # Loop through each query
            For($i = 0; $i -lt $queries.count; $i  )
            {
                $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
                $SqlCmd.CommandText = $queries[$i]
                $SqlCmd.Connection = $SqlConnection
                $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
                $SqlAdapter.SelectCommand = $SqlCmd
                $DataSet = New-Object System.Data.DataSet
                $SqlAdapter.Fill($DataSet)
                $DataSet.Tables[0] | Export-CSV -NoTypeInformation -Path "C:DevblahHeaderDetail$($sheetnames[$i])_$FileNameDate-000.csv" -Delimiter '|'
                
            }
        }#End Process
        End
        {
            $SqlConnection.Close()
        }
    }#End function run-query.
    
    $queries = @()
    
    $queries  = @'
    SET NOCOUNT ON
    SET ANSI_WARNINGS OFF
    /*FE Header*/
      SELECT [sContractNumber] as ContractNumber,
      into #Temp
      FROM  C
      INNER JOIN  D ON C.Id=D.iId
      WHERE c.sContractNumber in ('$sContractNumbers')
      order by sContractNumber
    
    declare @TotalNewContracts int = 0
    declare @TotalCanContracts int = 0
    declare @TotalExpContracts int = 0
    
    set @TotalNewContracts = (select COUNT(fe.ContractNumber) from #temp fe where Record_Type = 'P')
    set @TotalCanContracts = (select COUNT(fe.ContractNumber) from #temp fe where Record_Type = 'C')
    
    select
    count(contractnumber) as 'Total Number of All Contracts',
    FROM #temp ;
    
    drop table #Temp;
    '@
    
    $queries  = @'
    SET NOCOUNT ON
    SET ANSI_WARNINGS OFF
    
    /*FE Header*/
      SELECT [sContractNumber] as ContractNumber,
      into #Table
      FROM [pcmi_warranty_custom_twsi].[dbo].[Contract_Header] C
      INNER JOIN [pcmi_warranty_custom_twsi].[dbo].[Dealer_Header] D ON C.iDealerId=D.iId
      WHERE c.sContractNumber in ('$sContractNumbers')
      order by sContractNumber
    
    SELECT ContractNumber,
    FROM #temp FE;
    
    drop table #Temp;
    '@
    
    $sheetnames = @()
    $sheetnames  = 'Header'
    $sheetnames  = 'Details'
    
    #FileName
    $FileNameDate = Get-Date -f 'yyyyMMdd'
    Run-Query -queries $queries -sheetnames $sheetnames
    #Removes Double Quotes from File
    (Get-Content C:DevblahHeaderDetailHeader_$FileNameDate-000.csv) | % {$_ -replace '"', ''} | out-file -FilePath C:DevblahHeaderHeader_$FileNameDate-000.csv -Force -Encoding ascii
    (Get-Content C:DevblahHeaderDetailDetails_$FileNameDate-000.csv) | % {$_ -replace '"', ''} | out-file -FilePath C:DevblahDetailDetails_$FileNameDate-000.csv -Force -Encoding ascii
    #Add Double Pipes as Delimter
    (Get-Content C:DevblahHeaderHeader_$FileNameDate-000.csv) | % {$_ -replace "|", "||"} | out-file -FilePath C:DevblahHeaderHeader_$FileNameDate-000.csv -Force -Encoding ascii
    (Get-Content C:DevblahDetailDetails_$FileNameDate-000.csv) | % {$_ -replace "|", "||"} | out-file -FilePath C:DevblahDetailDetails_$FileNameDate-000.csv -Force -Encoding ascii
    #Add Header Detail Row to Detail File
    #Header Path
    $HeaderPath = "C:DevblahHeaderHeader_$FileNameDate-000.csv"
    #Detail Path
    $DetailsPath = "C:DevblahDetailDetails_$FileNameDate-000.csv"
    #Gets second row of header file and sets it as a varaible
    $HeadeDetail = Get-Content $HeaderPath -TotalCount 2 | Select-Object -Last 1;
    #print the header detail row
    $HeadeDetail
    #Get Detail File content
    $DetailContent = Get-Content -Path $DetailsPath
    #Add Header Detail row to Detail file
    $DetailContent[1] = "{0}`r`n{1}" -f $HeadeDetail, $DetailContent[1] 
    #Save Detail File
    $DetailContent | Set-Content "C:Devblahblah$FileNameDate-000.csv" -Force -Encoding ascii
    #Set the file name
    $SourceFile = "C:Devblahblah$FileNameDate-000.csv"
    $DestinationFolder = 'C:Devblah'
    $HeaderFile = "C:DevblahHeaderHeader_$FileNameDate-000.csv"
    $DetailFile = "C:DevblahDetailDetails_$FileNameDate-000.csv"
    $HDestinationFolder = 'C:DevblahHeader'
    $DDestinationFolder = 'C:DevblahDetail'
    
    if (Test-Path $SourceFile)
    { 
        $latest = Get-ChildItem -Path $DestinationFolder| Sort-Object Name -Descending | Select-Object -First 1
        #split the latest filename, increment the number, then re-assemble new filename:
        $newFileName = $latest.BaseName.Split('-')[0]   "-"   ([int]$latest.BaseName.Split('-')[1]   1).ToString().PadLeft(3,"0")   $latest.Extension
        Move-Item -path $SourceFile -destination $DestinationFolder""$newFileName
    }
    if (Test-Path $HeaderFile)
    { 
        $latest = Get-ChildItem -Path $HDestinationFolder| Sort-Object Name -Descending | Select-Object -First 1
        #split the latest filename, increment the number, then re-assemble new filename:
        $newFileName = $latest.BaseName.Split('-')[0]   "-"   ([int]$latest.BaseName.Split('-')[1]   1).ToString().PadLeft(3,"0")   $latest.Extension
        Move-Item -path $HeaderFile -destination $HDestinationFolder""$newFileName
    }
    if (Test-Path $DetailFile)
    { 
        $latest = Get-ChildItem -Path $DDestinationFolder| Sort-Object Name -Descending | Select-Object -First 1
        #split the latest filename, increment the number, then re-assemble new filename:
        $newFileName = $latest.BaseName.Split('-')[0]   "-"   ([int]$latest.BaseName.Split('-')[1]   1).ToString().PadLeft(3,"0")   $latest.Extension
        Move-Item -path $DetailFile -destination $DDestinationFolder""$newFileName
    }
    
    #Creates backup folder with corresponding date and places the file
    $FolderName = Get-Date -f 'MMdd'
    $FolderToCreate = "C:Devblah$FolderName"
    if (!(Test-Path $FolderToCreate -PathType Container)) {
        New-Item -ItemType Directory -Force -Path $FolderToCreate
    }
    Copy-Item -Path "$DestinationFolderTWFE*.csv" -Destination $FoldertoCreate -force; 
    
    $ODrive = 'O:blahblahblah'
    $FolderToCopy = "O:blahblahblah$FolderName"
    $LatestFile = Get-ChildItem -Path "$DestinationFolder$FolderName" -Name TWFE*.csv | Sort-Object -Descending | Select-Object -First 1
    if (!(Test-Path $FolderToCopy -PathType Container)) {
        Copy-Item -Path "$DestinationFolder$FolderName" -Destination $FolderToCopy -Recurse -Force -ErrorAction Continue
    }
    
    if ((Test-Path $FolderToCopy -PathType Container)) {
        Copy-Item -Path $LatestFile -Destination $FolderToCopy -Recurse -Force -ErrorAction Continue
    }

  

Комментарии:

1. Это… много кода. Вашей первой задачей может быть разделение ее на функции, которые вы можете протестировать независимо, чтобы определить, в чем проблема. Одна вещь, которую нужно попробовать в качестве нулевого результата, — это write-host ваши SQL-запросы по мере их выполнения и убедитесь, что они выполняют то, что вы от них ожидаете…

2. Я думал о создании sql scripts SP и использовании метода ExcuteStoreproc, который я могу передать params. все еще не уверен, что это решит мою проблему, но я начну с этого. Спасибо за совет