我试图从PowerShell中的连接字符串中获取数据库名称。
"Server=server\instance;uid=User;pwd=Hello;Database=SomeName;"
我可以想到两种方法,要么搜索字符串Database
,直到第一个;
之后将=
上的字符串拆分并选择数据库名称 - 但我真的不知道该怎么做。
第二种方式可以是这样的DBConnectionStringBuilder
:
$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.set_ConnectionString($cstring)
[string]$Database = ($sb | ? {$_.Keys -eq 'Database'}).value
但是这样,无论我多么努力地过滤Databasename,它都不会给我返回的数据库名。
问题:从连接字符串中获取Databasename的最佳方法是什么?
答案 0 :(得分:6)
使用第二种方法,但要简化它:
$cstring = "Server=server\instance;uid=User;pwd=Hello;Database=SomeName;"
$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.set_ConnectionString($cstring)
$Database = $sb.database
这完全没问题。
如果你想避免在密钥不存在的情况下出现错误,有很多方法可以做到这一点,首先寻找密钥的惯用方法是:
if ($sb.HasKey('Database')) {
$Database = $sb.Database
}
或对象自己的TryGetValue
方法:
if ($sb.TryGetValue('Database', [ref] $Database)) {
# It was successful
# $Database already contains the value, you can use it.
} else {
# The key didn't exist.
}
我不建议在这种情况下使用这些,因为数据库连接字符串格式有一定的灵活性,以及为什么让代码知道所有可能性并尝试在代码已经写入时正确处理它们(对象你在上面使用了吗?
但是为了完整性,我会通过拆分和正则表达式匹配和捕获来实现:
$cstring -split '\s*;\s*' |
ForEach-Object -Process {
if ($_ -imatch '^Database=(?<dbname>.+)$') {
$Database = $Matches.dbname
}
}
所以在这里,我首先分裂出一个由任意数量的空格包围的分号;
。然后针对另一个正则表达式检查每个元素(应该只是键值对),专门查找Database=
,然后在名为{{1的命名捕获组中捕获字符串结尾之前的内容。 }}。如果匹配成功,则将捕获组的结果分配给变量。
当一个存在时,我仍然更喜欢一个合适的解析器。
答案 1 :(得分:0)
试试这个
"Server=server\instance;uid=User;pwd=Hello;Database=SomeName;".split(";") |
%{[pscustomobject]@{Property=$_.Split("=")[0];Value=$_.Split("=")[1]}} |
where Property -eq "Database" | select Value
答案 2 :(得分:0)
其他解决方案
$template=@"
{Property*:Abc123}={Value:Test123}
{Property*:Def}={Value:XX}
"@
"Server=server\instance;uid=User;pwd=Hello;Database=SomeName;".replace(";", "`r`n") | ConvertFrom-String -TemplateContent $template |
where Property -eq "Database" | select Value