Sql server 为什么此命令在SQLServerManagementStudio中工作,而不是在PowerShell中工作

Sql server 为什么此命令在SQLServerManagementStudio中工作,而不是在PowerShell中工作,sql-server,powershell,Sql Server,Powershell,我有以下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(D

我有以下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
在SQLServerManagementStudio中,这可以毫无问题地工作,并返回表及其格式

昨天,这在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

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不会抱怨如果您拼错了变量名,它将创建一个新的空变量名

改用新的。通过这种方式,您可以编写以下代码:

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}

使用之后应该跟着切换上下文@revoua no.USE是仅由SSMS和sqlcmd理解的批处理命令。它不是T-SQLcommand@SimonS
USE
根本不应该被使用。首先连接到所需的数据库
USE
是SSMS或sqlcmd可以理解的批处理命令,它不是T-SQL命令。@PanagiotisKanavosthanks@SimonS
仍然不走运
不是错误消息。这次怎么了?在SSMS中运行查询时是否有任何结果?你确定没有错别字吗?谢谢,不过我的剧本没有错。奇怪的是,
$表中没有输出。但是如果我使用
$tables.count
它将返回
8
。奇怪的是,如果你不提问题,至少是一条错误信息,没有人能帮你。顺便问一下,为什么要使用ADO.NET类而不是SQL Server Powershell cmdlet?Powershell不会抱怨如果您拼写错误了一个变量,它会创建一个新的空变量,名称拼写错误。我在问题中非常清楚地解释了我的问题。我不使用sqlserver cmdlet,因为我不在SQL server本身上。@SimonS很遗憾,您没有解释它。“它是空的”可以简单地表示你有一个打字错误。事实上,99%的情况下,这就是空结果的原因。请注意我提供的查询。我没有在本地服务器上运行它们。在我的机器上,我实际上使用了远程服务器的IP