I have the following SQL command which reads the index fragmentation of my database called Logik
:
USE Logik
SELECT
OBJECT_NAME(ind.OBJECT_ID) AS TableName,
ind.name AS IndexName, indexstats.index_type_desc AS IndexType,
indexstats.avg_fragmentation_in_percent
FROM
sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats
INNER JOIN
sys.indexes ind ON ind.object_id = indexstats.object_id
AND ind.index_id = indexstats.index_id
WHERE
indexstats.avg_fragmentation_in_percent > 0
In SQL Server Management Studio, this works without a problem and returns the tables with their fragementation.
Yesterday, this also worked from PowerShell. I didn't change any code but today it doesn't work anymore. Does anyone have an idea why?
$Data
will stay empty:
param(
[string]$connectionstring = "Server=some\instance;uid=sa;pwd=dfdfdfdf;Database=Logik;Integrated Security=False;MultipleActiveResultSets=True;Connection Timeout=900;"
)
# Stop bei Fehler
$ErrorActionPreference = "SilentlyContinue"
$database = "logik"
# Database Connection herstellen
$con = New-Object System.Data.SqlClient.SqlConnection
$con.ConnectionString = $connectionstring
Try { $con.Open() }
Catch { Throw $_.Exception.Message }
# command einlesen um Fragmentation zu lesen
$command = "
USE Logik
SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName,
ind.name AS IndexName, indexstats.index_type_desc AS IndexType,
indexstats.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats
INNER JOIN sys.indexes ind
ON ind.object_id = indexstats.object_id
AND ind.index_id = indexstats.index_id
WHERE indexstats.avg_fragmentation_in_percent > 0"
# Command Zusammensetzen
$cmd = New-Object System.Data.SqlClient.SqlCommand
$cmd.CommandText = $command
$cmd.Connection = $con
$cmd.CommandTimeout = 2000
# Execute Command
Try { $result = $cmd.ExecuteReader() }
Catch { Throw $_.Exception.Message }
# Output von Resultat
$Data = New-Object System.Data.DataTable
$Data.load($result)
The whole thing is strange because, after I load the data, I put it into another variable $tables
, and I want to throw when $tables
is empty.
I use this code to check if there is any data loaded, and it returns an empty row for $tables
, but $tables.count
returns 8. how is that possible?
# Logik Tabellen
$tables = $Data | ? { $_.avg_fragmentation_in_percent -ge 5 -and $_.IndexName -ne 0 }
if (!$tables) { Throw "Keine Datenbank gefunden, oder keine Höher als 5% Fragmentation" }
$tables.count ; $tables ; pause
USE
shouldn't be used at all. It's a batch command understood by SSMS or sqlcmd, not a T-SQL command.
In this case, the connection string connects to the Logik
database already. There's no reason to use USE
to switch to it.
Just use :
$command = "
SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName,
ind.name AS IndexName, indexstats.index_type_desc AS IndexType,
...
If you want to use tables from different databases in the same query, use a three-part name, eg: MyDatabase.dbo.ThatTableName
.
You should probably not use the ADO.NET library inside a Powershell script. Powershell won't complain if you misspell a variable name, it will create a new empty one.
Use the SQL Server Powershell provider instead. This way you can write the following code :
Import-Module Sqlps -DisableNameChecking;
cd SQL\MyRemoteServer\DEFAULT\Databases\MyDatabase
$result=Invoke-SqlCmd -Query "SELECT @@VERSION;"
The $result
variable will hold the results of the query after that.
If the query returns multile rows, or even a single one with multiple fields, you'll get back an array of objects with properties that match the columns.
The following query :
$tables=Invoke-SqlCmd -Query "SELECT * from sys.tables"
Will return the contents of the sys.tables
table. You can access individual columns as properties. This script will return all table names :
$tables | %{ $_.name;}
Chained together :
Invoke-SqlCmd -Query "SELECT * from sys.tables" | % {$_.name}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.