在Powershell中将SQL查询作为数组返回

时间:2010-10-26 21:53:27

标签: sql-server arrays sql-server-2008 powershell

我有一台SQL 2008 Ent服务器,服务器DEVSQLSRV上有数据库“DBOne”,“DBTwo”,“DBThree”。

这是我的Powershell脚本:

$DBNameList = (Invoke-SQLCmd -query "select Name from sysdatabases" -Server DEVSQLSRV)

这会产生我想要的数据库名称列表:

Name
-----
DBOne
DBTwo
DBThree

我一直认为,作为列表返回的任何内容都是Powershell中的数组。但是,当我在Powershell中尝试这个时:

$DBNameList -contains 'DBTwo'

它回来时有“False”而不是“True”,这让我相信我的列表不是真正的数组。

知道我在这里缺少什么吗?

非常感谢!

情绪

7 个答案:

答案 0 :(得分:10)

我会这样做:

$DBNameList = @(Invoke-SQLCmd -query "select Name from sysdatabases" -Server DEVSQLSRV) | select-object -expand Name

这将为您提供一系列名称。选项-contains应该可以正常工作。

答案 1 :(得分:3)

原始帖子中缺少的是某种类型的转换,从对象到数组。

Powershell输出$ DBNameList的结果,因为它有点解释对象。但是如果你需要操作这个对象并从中识别出一个特定的项目,这就是我使用的方法:

$Itm = "DBTwo"
$DBNameList = @(Invoke-SQLCmd -query "select Name from sysdatabases" -Server DEVSQLSRV)
$NameList = @($DBNameList | select-object -ExpandProperty Name)
$Name = ($NameList.Split()).Contains($Itm)
Write-Output $Name
  

我自己一直在寻找这个并终于解决了,所以我希望它可以帮助别人!

答案 2 :(得分:0)

Name标头表明它是一个具有Name属性的单个对象,该属性是一个数组。

我估计初始化一个空PS阵列:

$DBNameList = (Invoke-SQLCmd -query "select Name from sysdatabases" -Server DEVSQLSRV)
[Array]$DbNames = @()
$DBNameList.Name | ForEach-Object {$DbNames += $_}
$DbNames -contains "DBTwo"

运气好吗?

答案 3 :(得分:0)

您的代码......

$DBNameList = (Invoke-SQLCmd -query "select Name from sysdatabases" -Server DEVSQLSRV)

...给你Datarows回来......

您可以使用

进行检查
$DBNameList | Get-Member

您还可以看到有一个名为“Name”的属性。

如果要检查$ DBNameList中的某个数据行是否包含“DBTwo”的名称,则需要编写以下内容:

$DBNameList.Name -contains 'DBTwo'

答案 4 :(得分:0)

万一其他人因为害怕而最终来到这里,他们将不得不在DataRow对象响应中手动键入每个属性的名称,以便将多个列放入数组中,不用担心,有一个方便的属性,称为“ ItemArray”,可提供您所需的内容。

(Invoke-SQLCmd -query "select Name from sysdatabases").ItemArray -contains 'DBTwo'
  

这里有很多很好的答案可以解决此特定OP的繁琐问题,但是当列列表变长时,这会使事情变得简单得多。

(Invoke-SQLCmd -query "select DBID,Name,Version from sysdatabases")[0].ItemArray -join ','
  

1,master,852

答案 5 :(得分:0)

阅读所有这些复杂的答案,我意识到这里有一个简单的答案:

$ DBNameList.Name-包含“ DBTwo”

这应该返回true。 最初提取数据(数据库名称)将返回一个对象数组。每个对象都有许多属性。但是在逻辑测试中,您试图将整个对象与单个字符串进行比较。您需要将对象(.Name)的单个属性与字符串进行比较。

答案 6 :(得分:-1)

Powershell还是非常新的(不到两周):如果你的查询包含多个列和行,我建议你试试这个...多维数组。这是我第一次尝试这个,在检查网络后,鉴于我找不到一个简单的直接解决方案,我最终编写了自己的解决方案。这是您试用和使用的全套示例代码。


以下完整的示例代码....

    #############################################################################################
    # RDSago
    #  RDSago@gmail.com
    #  09/20/2014
    #############################################################################################   
    #
    #  Capturing database size information from a collection of servers
    #    and returning that back to an array that can be used to populate
    #    a SQL table that can be used for monitoring database growth remotely.
    #    RDSago, RDSago@gmail.com
    #
    #  Note, SQL data retrieved in this manner, does not have to be parsed
    #    before it is consumed and used elsewhere, just like any array you have defined.
    #    The data only needs to be addressed by its ".identityname" captured in the 
    #    array $queryResults (shown below).
    #
    ############################################################################################

    #############################################################################################
    # T-SQL for creating table to hold data returned
    #
    # CREATE TABLE [dba].[tbl_dbfilesize](
    #   [ServerNameInstance] [varchar](20) NULL,
    #   [DatabaseName] [varchar](30) NULL,
    #   [DataFileSizeMB] [numeric](20, 0) NULL,
    #   [LogFileSizeMB] [numeric](20, 0) NULL,
    #   [TotalDatabaseSizeMB] [numeric](20, 0) NULL,
    #   [CollectionDate] [date] NULL
    #   ) ON [PRIMARY]
    #############################################################################################




    Try
    {

    #define your connection points

        # first create an array that will hold the server/instance name of the servers you wish to audit
        # the first sever assumes a named instance, the second a default instance name.
        $SourceServerName = @("ServerName01/InstanceName", "ServerName02", "ServerName03")  # Server you will retrieve data from

        #next define the server connection for where you will write your data back to
        $TargetServerInstance = "TaretServerName"

     # define your sql query that will be used to pull data from SQL on the Source Server
       $qryDatabaseInfo = "
         SELECT @@ServerName as ServerNameInstance,
         DB.name as DatabaseName,
         SUM(CASE WHEN type = 0 THEN MF.size * 8 / 1024 ELSE 0 END) AS DataFileSizeMB,
         SUM(CASE WHEN type = 1 THEN MF.size * 8 / 1024 ELSE 0 END) AS LogFileSizeMB,
         SUM(CASE WHEN type = 1 THEN MF.size * 8 / 1024 ELSE 0 END) + SUM(CASE WHEN type = 0 THEN MF.size * 8 / 1024 ELSE 0 END) AS TotalDatabaseSizeMB
         FROM sys.master_files MF
         JOIN sys.databases DB ON DB.database_id = MF.database_id
         GROUP BY DB.name
         ORDER BY DB.NAME ASC
         "

       #Loop through all the servers you wish to audit
       ForEach ($SourceServerName in $SourceServerNames)

           { 

            #execute query to pull data from server into an array
            $queryResults = @(Invoke-SQLCmd -query $qryDatabaseInfo -Server $SourceServerInstance)

            # Next, construct your insert statement from data in your $queryresults array.

             Foreach ($queryResult in $queryResults)
                {

                  $query = "
                  Insert Into [DBS_AUDIT_SERVERS].[dba].[tbl_dbfilesize]
                     ([ServerNameInstance],
                     [DatabaseName],
                     [DataFileSizeMB],
                     [LogFileSizeMB],
                     [TotalDatabaseSizeMB],
                     [CollectionDate])
                   Values
                      (" + 
                       "'" + $SourceServerInstance + "'," +
                       "'" + $queryResult.DatabaseName + "'," +
                       "'" + $queryResult.DataFileSizeMB + "'," +
                       "'" + $queryResult.LogFileSizeMB + "'," +
                       "'" + $queryResult.TotalDatabaseSizeMB + "'," +
                       "'" + $Date + "'" +
                       ")"
                       ""
                    #execute insert statement for sql
                    Invoke-Sqlcmd -Query $query -ServerInstance $TargetServerInstance
                }       
           }
    }

    Catch [Exception]
       {
           $ErrorMessage = $_.Exception.Message
           Write-Host $ErrorMessage
       }


    Finally
       {
           Write-Host "Completed Successfully"
       }
    Return 0;