我正在尝试从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.
问题:从连接字符串中获取Databasename的最佳方法是什么?
使用第二种方法,但要简化它:
$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=(?.+)$') { $Database = $Matches.dbname } }
所以在这里,我首先分裂在;
由任意数量的空白包围的分号上.然后针对另一个正则表达式检查每个元素(应该只是键值对),专门查找Database=
,然后捕获在此之后发生的内容,直到字符串结尾,在一个名为的捕获组中dbname
.如果匹配成功,则将捕获组的结果分配给变量.
当一个存在时,我仍然更喜欢一个合适的解析器.