Есть ли «функция-подобная вещь», которая может выступать в качестве шаблона? - PullRequest
0 голосов
/ 03 мая 2020

У меня есть такой код, который повторяется несколько раз в каждом из моих условных утверждений / случаев. У меня есть 3 условия ... на данный момент, и все работает отлично, но я думаю, переформатирование сценария для более удобного чтения.

Один из способов, которые я подумал, - создать функцию, но проблема в том, что у меня есть время l oop, которое предназначено для определенного c сценария в каждом условном операторе, который отключается от Очередь, содержащая некоторые имена столбцов из файла.

, так что, основываясь на приведенном ниже коде, который я хочу вставить в какой-то шаблон, я не могу думать о том, как это может работать, потому что, как вы можете видеть, $ tb означает $ table, который я и открываю до к условным заявлениям в моем коде. если бы я включил в функцию все, что касается соединения с сервером и таблицы, то это означает, что когда я передаю «функцию», содержащую код, в циклы while, он будет создавать / создавать экземпляр таблицы на каждой итерации, что не имеет смысла и не имеет смысла. работать в любом случае.

, так что я думаю об использовании чего-то вроде аннотаций, что-то вроде шаблона, который не будет возвращать что-либо или нуждаться в разумных аргументах, как в противном случае функция. Вопрос в том, существует ли что-то подобное?

Это код, который одинаков во всех моих циклах while, которые я хотел бы где-то «сохранить» и просто передать им:

$dqHeader = $csvFileHeadersQueue.Dequeue()

$column = New-Object Microsoft.SqlServer.Management.Smo.Column($tb, $dqHeader, $DataType1)

if ($dqHeader -in $PrimaryKeys)
{
    # We require a primary key.

    $column.Nullable = $false
    #$column.Identity = $true #not needed with VarChar
    #$column.IdentitySeed = 1 #not needed with VarChar
    $tb.Columns.Add($column)

    $primaryKey = New-Object Microsoft.SqlServer.Management.Smo.Index($tb, "PK_$csvFileBaseName")
    $primaryKey.IndexType = [Microsoft.SqlServer.Management.Smo.IndexType]::ClusteredIndex
    $primaryKey.IndexKeyType = [Microsoft.SqlServer.Management.Smo.IndexKeyType]::DriPrimaryKey #Referential Integrity to prevent data inconsistency. Changes in primary keys must be updated in foreign keys.
    $primaryKey.IndexedColumns.Add((New-Object Microsoft.SqlServer.Management.Smo.IndexedColumn($primaryKey, $dqHeader)))
    $tb.Indexes.Add($primaryKey)
}
else
{
    $tb.Columns.Add($column)
}

воспринимайте это как головоломку часть, которая будет подходить сразу, когда будет предложено сделать это в цикле while, чтобы завершить эту «загадку»

1 Ответ

2 голосов
/ 03 мая 2020

Согласно комментарию:
вы можете поделиться (жестко закодированным) [ScriptBlock] ($template = {code in post goes here}) с while l oop (или функцией) и вызвать его, например, Invoke-Command $template или оператором вызова: &$template. Динамическое изменение выражения и использование таких команд, как Invoke-Expression или [ScriptBlock]::Create(), не очень хорошая идея из-за риска внедрения вредоносного кода (см .: # 1454 ).

Вы можете даже добавить параметров для вашей общей [ScriptBlock], например:

$Template = {
    [CmdletBinding()]Param ($DataType)
    $column = New-Object Microsoft.SqlServer.Management.Smo.Column($tb, $dqHeader, $DataType)
    ...
}

ForEach ($MyDataType in @('MyDataType')) {
    Invoke-Command $Template -ArgumentList $MyDataType
}

Но встречный вопрос остается: Почему бы просто не создать «вспомогательную» функцию ? :

Function template($DataType) {
    $column = New-Object Microsoft.SqlServer.Management.Smo.Column($tb, $dqHeader, $DataType)
    ...
}

ForEach ($MyDataType in @('MyDataType')) {
    template $MyDataType
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...