1

I'm trying to get the number of rows from a Microsoft SQL database table in Powershell as an integer and am stuck peeling the figure out of the object Powershell is returning.

I have;

$SQLServer = "MSSQL01"   $SQLDBName = "TheTable" $SqlQuery = "select count(*) from cases where opened_date =< '2014-07-30'"

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True"

$SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = $SqlQuery $SqlCmd.Connection = $SqlConnection

$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $SqlAdapter.SelectCommand = $SqlCmd

$DataSet = New-Object System.Data.DataSet $SqlAdapter.Fill($DataSet)

$SqlConnection.Close()

Now $DataSet.Tables[0] in this instance returns an object like;

Table Name
-----------

45

How can I grab just the 45 as an int?

1
  • 1
    Look at ExecuteScalar instead of filling an adapter Commented Jul 31, 2014 at 8:28

3 Answers 3

3

Look at ExecuteScalar:

$SQLServer = "MSSQL01"   
$SQLDBName = "TheTable" 
$SqlQuery = "select count(*) from cases where opened_date =< '2014-07-30'"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = $SqlQuery $SqlCmd.Connection = $SqlConnection
$SqlConnection.Open() 
$Rows= [Int32]$SqlCmd.ExecuteScalar()
$SqlConnection.Close()
Sign up to request clarification or add additional context in comments.

3 Comments

You should to remove $DataSet from the ExecuteScalar call. The method doesn't take a parameter and $DataSet isn't initialised in your example.
Seems like I'm close but I get "ExecuteScalar requires an open and available Connection. The connection's current state is closed", your example code above doesn't differ from mine but for the executescalar v filling an adapter, why does the connection now not open?
Updated. You need to explicitly open yourself.
2

Here's a version which provides two encapsulated functions, based on @jessehouwing's answer. This also handles an optional port, choice of TrustedAuth vs. User/Passwd Authentication, and an optional WHERE clause.

function createSqlConnection($sqlServer, $sqlPort, $dbName, $user, $password) {
    $sqlConnection = New-Object System.Data.SqlClient.sqlConnection
    if ($sqlPort) { $sqlServer = "$sqlServer,$sqlPort" }
    if ($user -and $password) {
        $sqlConnection.ConnectionString = "Server=$sqlServer; Database=$dbName; User Id=$user; Password=$password"
    } else {
        $sqlConnection.ConnectionString = "Server=$sqlServer; Database=$dbName; Integrated Security=True"
    }

    return $sqlConnection
}

function getRowCount($sqlConnection, $table, $where = "1=1") {
    $sqlQuery = "SELECT count(*) FROM $table WHERE $where"
    $sqlConnection.Open()
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand($sqlQuery, $sqlConnection)
    $row_count = [Int32] $SqlCmd.ExecuteScalar()
    $sqlConnection.Close()
    return $row_count
}

To use it:

$dbConn = createSqlConnection 'db-server' $null 'myDatabase' $user $password
$count = getRowCount $dbConn 'the_table'

1 Comment

Your optional where clause adds a nice SQL injection vulnerability to the function.
1

Using ExecuteScalar is a much better solution. If, for some reason, you want to stick with the DataSet use either:

$DataSet.Tables[0].'Table Name'

or

$DataSet.Tables[0] | Select-Object -ExpandProperty "Table Name"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.