Возврат SQL-запроса в виде массива в Powershell

у меня есть сервер SQL 2008 Ent с базами данных "DBOne", "DBTwo", "DBThree" на сервере DEVSQLSRV.

вот мой сценарий Powershell:

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

это создает мой желаемый список имен баз данных как:

Name
-----
DBOne
DBTwo
DBThree

я предположил, что все, что возвращается в виде списка, является массивом в Powershell. Однако, когда я затем попробую это в Powershell:

$DBNameList -contains 'DBTwo'

он возвращается имеет "False" вместо "True", что приводит меня к поверьте, что мой список не является фактическим массивом.

есть идеи, что я упускаю здесь?

спасибо!

эмо

5 ответов


Я бы сделал так:

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

это даст вам массив имен.Вариант -contains должно работать нормально.


в исходном сообщении отсутствует какой-либо тип преобразования из объекта в массив.

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

True

Я искал это сам некоторое время и, наконец, понял это, поэтому я надеюсь, что это поможет кому-то еще!


заголовок Name предполагает, что это один объект со свойством Name, которое является массивом.

Я считаю, инициализировать пустой массив PS:

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

что-нибудь?


ваш код...

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

...дает вам Datarows обратно..

вы можете проверить это с помощью

$DBNameList | Get-Member

вы также можете видеть, что есть свойство с именем "Name".

Если вы хотите проверить, содержит ли один из потоков данных в вашем $DBNameList имя "DBTwo", вам нужно будет написать следующее:

$DBNameList.Name -contains 'DBTwo'

все еще очень новый для 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;