我有以下SQL命令,它读取名为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
在SQL Server Management Studio中,这可以正常运行并返回表格及其分类。
昨天,这也来自PowerShell。我没有更改任何代码,但今天它不再起作用了。有谁知道为什么?
$Data
将保持空白:
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)
整个事情很奇怪,因为在我加载数据后,我把它放到另一个变量$tables
中,我想在$tables
为空时抛出。
我使用此代码检查是否加载了任何数据,并为$tables
返回一个空行,但$tables.count
返回8.这怎么可能?
# 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
答案 0 :(得分:1)
USE
根本不应该被使用。它是SSMS或sqlcmd理解的批处理命令,而不是T-SQL命令。
在这种情况下,连接字符串已经连接到Logik
数据库。我没有理由使用USE
切换到它。
只需使用:
$command = "
SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName,
ind.name AS IndexName, indexstats.index_type_desc AS IndexType,
...
如果要在同一查询中使用来自不同数据库的表,请使用由三部分组成的名称,例如:MyDatabase.dbo.ThatTableName
。
您可能不在Powershell脚本中使用ADO.NET库。如果拼错一个变量名,Powershell不会抱怨,它会创建一个新的空名称。
请改用SQL Server Powershell provider。这样您就可以编写以下代码:
Import-Module Sqlps -DisableNameChecking;
cd SQL\MyRemoteServer\DEFAULT\Databases\MyDatabase
$result=Invoke-SqlCmd -Query "SELECT @@VERSION;"
$result
变量将在此之后保存查询结果。
如果查询返回多行,或者甚至是一个包含多个字段的单行,您将返回一个具有与列匹配的属性的对象数组。
以下查询:
$tables=Invoke-SqlCmd -Query "SELECT * from sys.tables"
将返回sys.tables
表的内容。您可以将各个列作为属性进行访问。该脚本将返回所有表名:
$tables | %{ $_.name;}
链接在一起:
Invoke-SqlCmd -Query "SELECT * from sys.tables" | % {$_.name}