检查XML Node是否为true,如果是,则执行SQL语句

时间:2020-06-15 19:56:28

标签: powershell

我正在处理一个脚本,该脚本从环境的XML列表中读取并重复每个条目,还原数据库,在数据库上运行架构更改,然后备份所述数据库。我已经完成所有这些工作,但是我想向脚本添加逻辑,以包括在运行模式更改(如果XML节点存在)之前设置数据库所有者的步骤;

当前,如果我运行此命令,无论如何它都会写“未指定DBOwner”。

$dbOwnerExists = $($Environment.Backup.DatabaseBackup.DBOwner)

if ($dbOwnerExists -eq $true) {
    Invoke-Sqlcmd -ServerInstance "$($DatabaseBackup.Instance)" -Query "EXEC sp_changedbowner $($Environment.Backup.DatabaseBackup.DBOwner)"
} else {
    Write-Output 'No DBOwner Specified'
}

当前的XML看起来像这样

<Environments>

    <Environment Database="exampleDatabase">
        <Backup Restore="TRUE">
            <DatabaseBackups Instance="SQLInstance" SrcLocation="\\Hostname\c$\temp\example.bak" DstLocation="\\Hostname\c$\temp\example.bak" DBOwner="&quot;sa&quot;"/>
            <DatabaseBackups Instance="SQLInstance" SrcLocation="\\Hostname\c$\temp\example2.bak" DstLocation="\\Hostname\c$\temp\example2.bak"/>
        </Backup>
    </Environment>

</Environments>

powershell似乎不喜欢我检查XML中是否存在DBOwner的逻辑,也许$ true不是检查此内容的最佳方法?

2 个答案:

答案 0 :(得分:1)

我还没有看到您的完整代码,所以这是我能做的最好的事情。

让我们假设您将XML存储在变量$XML中,并且$XML的定义如下:

[xml]$xml = @"
<Environments>

    <Environment Database="exampleDatabase">
        <Backup Restore="TRUE">
            <DatabaseBackups Instance="SQLInstance" SrcLocation="\\Hostname\c$\temp\example.bak" DstLocation="\\Hostname\c$\temp\example.bak" DBOwner="&quot;sa&quot;"/>
            <DatabaseBackups Instance="SQLInstance" SrcLocation="\\Hostname\c$\temp\example2.bak" DstLocation="\\Hostname\c$\temp\example2.bak"/>
        </Backup>
    </Environment>

</Environments>
"@

您可以仅通过检查值来检查DBOwner是否存在

$XML.Environments.Environment.Backup.DatabaseBackups.DBOwner

使用XML的输出:

"sa"

但是要获取true/false值是否存在,可以像在回答中那样使用[bool]数据类型:

[bool]$XML.Environments.Environment.Backup.DatabaseBackups.DBOwner

但是我发现了一个小故障,如果节点不存在,它仍然会输出true:

[bool]$XML.Environments.Environment.Backup.DatabaseBackups.fasdasd
True

所以我将其更改为此。

[bool][string]$($XML.Environments.Environment.Backup.DatabaseBackups.DBOwner).trim

在这种情况下将输出:

True

并将其放入if语句中,因为它已经是布尔值了,因此可以将其放入in语句中,如下所示:

if([bool][string]$($XML.Environments.Environment.Backup.DatabaseBackups.DBOwner).trim){
Invoke-Sqlcmd -ServerInstance "$($DatabaseBackup.Instance)" -Query "EXEC sp_changedbowner $($Environment.Backup.DatabaseBackup.DBOwner)"
} else {
    Write-Output 'No DBOwner Specified'
}

要测试此方法是否可行,我们还可以尝试对不存在的东西(例如$XML.Environments.Environment.Backup.DatabaseBackups.SomethingThatDoesntExist)执行此操作,该返回值应为false,如下所示:

[bool][string]($XML.Environments.Environment.Backup.DatabaseBackups.SomethingThatDoesntExist).trim()
False

要测试我们可以做的if语句

if([bool][string]$($XML.Environments.Environment.Backup.DatabaseBackups.DBOwner).trim){
 Write-Output "Exists"
} else {
    Write-Warning 'No DBOwner Specified'
}

会输出

Exists

,我们还可以测试它是否不存在

if([bool][string]$($XML.Environments.Environment.Backup.DatabaseBackups.fasdasd).trim){
 Write-Output "Exists"
} else {
    Write-Warning 'No DBOwner Specified'
}

输出为:

WARNING: No DBOwner Specified

注意
[bool]语句中的if是不必要的,因为if已经将事物转换为布尔值,但我只是将其放入为了更容易理解,它也可以正常工作:

if([string]$($XML.Environments.Environment.Backup.DatabaseBackups.fasdasd).trim){
 Write-Output "Exists"
} else {
    Write-Warning 'No DBOwner Specified'
}

答案 1 :(得分:0)

我可以通过以下方法弄清楚这一点,这对我来说足够好了!

$dbOwnerExists=$null
$dbOwnerExists = $($DatabaseBackup.DBOwner)
if ($dbOwnerExists) {
    Invoke-Sqlcmd -ServerInstance "$($DatabaseBackup.Instance)" -Query "USE $($Environment.Database) EXEC sp_changedbowner '$($DatabaseBackup.DBOwner)'"
} else {
    Write-Output 'No DBOwner Specified'
}