PowerShell字符串中的变量必须在哪里初始化?

PowerShell字符串中的变量必须在哪里初始化?,powershell,heredoc,Powershell,Heredoc,我想在PowerShell脚本的here字符串中使用一个相当复杂的SQL查询。在查询中,我想用PowerShell变量替换某些值。我试图准确地理解我需要在何处声明和初始化将在here字符串中使用的变量 简化示例: $SqlQuery = @" update MyTable set foo = $bar where baz = $quux "@ ... foreach ($part in $parts) { $bar = $part[0] $quux = $part[1]

我想在PowerShell脚本的here字符串中使用一个相当复杂的SQL查询。在查询中,我想用PowerShell变量替换某些值。我试图准确地理解我需要在何处声明和初始化将在here字符串中使用的变量

简化示例:

$SqlQuery = @"
update MyTable 
set foo = $bar
where baz = $quux
"@

...

foreach ($part in $parts) {
    $bar = $part[0]
    $quux = $part[1]

    Run-SqlNonQuery $SqlQuery    #Run-SqlNonQuery is a funct. that executes the query
}
我在顶部声明here字符串,它引用了两个PowerShell变量,$bar和$qux,它们在循环中每次都会更改

但是,当我运行脚本时,会出现错误。运行SQL跟踪时,PS脚本中PowerShell变量出现的位置没有值

在这样的字符串中调用PowerShell变量时,是否会对其进行插值?我是否需要将整个here字符串放入初始化变量的循环中?这种东西的正确结构是什么

我正在Windows 7、.Net 4和VS2010上运行PowerShell。我不清楚这个版本<代码>$Host返回

Name             : PowerConsole
Version          : 1.0.30222.0
PSVersion             2.0                                                      
PSCompatibleVersions  {1.0, 2.0}
BuildVersion          6.1.7601.17514
但是
$pVersionTable
返回

Name             : PowerConsole
Version          : 1.0.30222.0
PSVersion             2.0                                                      
PSCompatibleVersions  {1.0, 2.0}
BuildVersion          6.1.7601.17514

编辑以包含马克的建议 假设您将数组的顺序与{x}等使用的顺序部分匹配

$SqlQuery = @"
update MyTable 
set foo = {0}
where baz = {1}
"@

...

foreach ($part in $parts) {
    Run-SqlNonQuery $SqlQuery -f $part    #Run-SqlNonQuery is a funct. that executes the query
}

原版

这应该可以完成任务

$SqlQuery = @"
update MyTable 
set foo = {0}
where baz = {1}
"@

...

foreach ($part in $parts) {
    $bar = $part[0]
    $quux = $part[1]

    Run-SqlNonQuery $SqlQuery -f $bar, $quux     #Run-SqlNonQuery is a funct. that executes the query
}
如果您想了解更多信息,请使用谷歌“powershell字符串格式”

嗯,, 马特

试试这个(单引号字符串):

通常,在分配变量(在循环内部)后,需要声明here字符串。可以使用子表达式展开值(例如$(…):


正如Shay所指出的,here字符串中的变量需要先声明,然后才能在here字符串中使用。我曾有机会移动它,只是为了使脚本更易于阅读/维护,并使用了一个脚本块:

$MakeHereString = {
@"

Variables 1-3 are:
Variable 1 = $variable1
Variable 2 = $variable2
Variable 3 = $variable3
"@
}

$Variable1 = "First"
$Variable2 = "Second"
$Variable3 = "Third"

&$MakeHereString

Variables 1-3 are:
Variable 1 = First
Variable 2 = Second
Variable 3 = Third
例如:

$SqlQuery = {
@"
update MyTable 
set foo = $bar
where baz = $quux
"@
}
...

foreach ($part in $parts) {
    $bar = $part[0]
    $quux = $part[1]

    Run-SqlNonQuery (&$SqlQuery)    #Run-SqlNonQuery is a funct. that    executes the query
}

PS.PowerShell版本2随Windows 7提供。哦,非常酷!我专注于变量插值,没有想到字符串格式——这非常有效。谢谢字符串格式化程序采用数组:
runsqlnonquery$SqlQuery-f$part
也可以。保存您创建变量只是为了传递它们。如果
Run SqlNonQuery
支持SQL参数,您可能可以更好地解决此任务。是吗?@Roman,不,不是--我当时正沿着这条路走,发现自己准备用PS编写一个完整的SQL DAL来支持存储过程、任意参数等,这是一个很大的开销,但没有多少好处。脚本编写的方式似乎是进行变量替换或插值,它很好而且简单,只是没有给出我需要的结果。我现在有两种解决方案可供选择——一种是语法简单但必须计算占位符的解决方案,另一种是使用描述性变量名但语法模糊的解决方案。注意这个问题:如果你打算用这种方式处理字符串数据(变量插值),不要忘记用一个或多个单引号转义(用
'
替换
'
)。谢谢,关于引号的好提示。在大多数情况下,我的变量用于引号内的文本,比如
setfoo='{0}'
,但并不总是这样!在第一次迭代中,here字符串的$bar和$qux值不都是空的吗?然后,在每次迭代之后都会有一次传递?你的意思是在here字符串上使用单引号吗?这正是我希望避免的——here字符串很长,我真的不想在每次循环迭代中重新声明它,也不想用一个大的、主要是静态的声明来扰乱我的循环。这在技术上是可行的,但不是最好的解决方案。@Shay,现在更好了!显式调用..ExpandString()有点冗长,但这让事情变得很清楚,在here字符串中保留命名变量是一个很好的奖励+1.这比Shay的解决方案要好一点,因为here字符串在循环之外,但语法比Matt的解决方案要笨拙得多:脚本块和子表达式不容易编写,也不容易阅读。这是可行的,但是Matt的字符串格式解决方案是最好的(也是第一个!)谢谢,tho。我想这是主观的。我会考虑用格式枚举替换在这里的字符串中的描述性变量名,使这里的字符串更难跟踪和调试,如果长度很长并且包含许多替换,则是特殊的。是的,绝对主观的;我同意在计算占位符时很容易迷路。但是当我看到“$(&$SqlQuery)”时,我想到一个卡通人物在诅咒我;-)--对我的口味来说,这里有点太神奇了(现在我要看看那个符号是怎么做的!)看起来我可能在美元上犯了错误。其实没必要。运行SqlNonQuery(&$SqlQuery)似乎也能很好地工作,如果这能让它变得更简单的话。很酷,我也会尝试一下这种方法。谢谢