2017-10-20 49 views
0
此命令工作

我有以下SQL命令读取我的数据库的索引碎片称为Logik为什么在SQL Server Management Studio,但不能从PowerShell的

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中,这个工程没有一个问题,并返回与他们的fragementation表。

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

使用应遵循GO - 确乎上下文切换; – revoua

+1

@revoua no。 USE是仅由SSMS和sqlcmd理解的*批处理*命令。这不是一个T-SQL命令 –

+2

@SimonS不应该使用@SimonS。首先连接到你想要的数据库。 'USE'是SSMS或sqlcmd可以理解的批处理命令,它不是T-SQL命令。 –

回答

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变量将举行查询后的结果。

如果查询返回multile行,或者甚至包含多个行的单个行,那么您将返回一个具有与列匹配的属性的对象数组。

下面的查询:

$tables=Invoke-SqlCmd -Query "SELECT * from sys.tables" 

将返回sys.tables表的内容。您可以将各个列作为属性进行访问。该脚本将返回所有的表名:

$tables | %{ $_.name;} 

链接在一起:

Invoke-SqlCmd -Query "SELECT * from sys.tables" | % {$_.name} 
+0

谢谢,尽管我的脚本没有运气。奇怪的是,'$ tables'没有输出。但如果我使用'$ tables.count',它会返回'8'。奇怪的 – SimonS

+0

没有人可以帮助,如果你没有提到什么是错的,至少一个错误信息。顺便说一句,你为什么使用ADO.NET类而不是SQL Server Powershell cmdlet? PowerShell不会抱怨,如果你拼错一个变量,它会创建一个*新的空*错误的名称 –

+0

我解释我的问题很清楚的问题。我不使用sqlserver cmdlet,因为我不在SQL服务器本身。 – SimonS

相关问题