首页 > 解决方案 > 检查 XML Node 是否为真,如果是,则执行 SQL 语句

问题描述

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

目前,如果我运行它,无论如何它都会写入“未指定 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 不是检查这个的最佳方法?

标签: powershell

解决方案


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

假设您将 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]s是不必要的,因为已经将事物转换为布尔值,但我只是将其放入以便更容易理解,这也可以正常工作:ifif

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

推荐阅读