【问题标题】:Return SQL Query as Array in Powershell在 Powershell 中将 SQL 查询作为数组返回
【发布时间】:2011-05-01 00:16:07
【问题描述】:

我有一个 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”,这让我相信我的列表不是一个实际的数组。

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

非常感谢!

情绪

【问题讨论】:

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


    【解决方案1】:

    我会这样做:

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

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

    【讨论】:

      【解决方案2】:

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

      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
      

      是的

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

      【讨论】:

        【解决方案3】:

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

        我估计初始化一个空的 PS 数组:

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

        运气好吗?

        【讨论】:

          【解决方案4】:

          你的代码...

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

          ...将 Datarows 还给您..

          您可以使用

          进行检查
          $DBNameList | Get-Member
          

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

          如果您想检查 $DBNameList 中的数据行之一是否包含“DBTwo”的名称,您需要将其编写如下:

          $DBNameList.Name -contains 'DBTwo'
          

          【讨论】:

            【解决方案5】:

            如果其他人因为害怕而不得不手动键入 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,大师,852

            【讨论】:

              【解决方案6】:

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

              $DBNameList.Name - 包含“DBTwo”

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

              【讨论】:

                【解决方案7】:

                对 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;
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-10-17
                  • 1970-01-01
                  • 2017-12-05
                  • 2015-10-05
                  • 2016-01-03
                  • 2020-07-04
                  • 2012-04-01
                  相关资源
                  最近更新 更多