J'essaie de lire les données d'une table SQL dans un script PowerShell. Je peux voir les données dans le lecteur, mais lorsque vous les lisez à l'aide de While (readerobject.read()){}
, elles ne vont pas à l'intérieur de la boucle.
Powershell :
$cmd = $sqlConn.CreateCommand()
$cmd.CommandText ="SELECT * from user"
$movedUserDetails = $cmd.ExecuteReader()
while ($movedUserDetails.Read())
{
"[0] : " + $movedUserDetails.GetValue(0)
}
$movedUserDetails.Close()
La syntaxe est correcte, mais vous ne faites rien avec la valeur une fois dans la boucle. Vous voudrez le persister d'une manière ou d'une autre. Voici un exemple d'exécution de SQL de base à l'intérieur de powershell, avec deux types de commandes (Text/SP) et deux méthodes d'exécution différentes (DataAdapter/DataReader). Chacun des deux devrait bien fonctionner.
# config
$svr = "serverName"
$db = "databaseName"
# connection
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server=$svr;Database=$db;Integrated Security=True"
$sqlConnection.Open()
# command A - text
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$sqlCmd.Connection = $sqlConnection
$sqlCmd.CommandText = "SELECT name AS TABLE_NAME FROM sys.tables"
# command B - stored procedure
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$sqlCmd.Connection = $sqlConnection
$sqlCmd.CommandText = "sys.sp_tables"
$sqlCmd.CommandType = [System.Data.CommandType]::StoredProcedure
$sqlCmd.Parameters.Add("@table_owner", "dbo")
# execute A - data reader
$reader = $sqlCmd.ExecuteReader()
$tables = @()
while ($reader.Read()) {
$tables += $reader["TABLE_NAME"]
}
$reader.Close()
# execute B - data adapter
$dataTable = New-Object System.Data.DataTable
$sqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$sqlAdapter.SelectCommand = $sqlCmd
$sqlAdapter.Fill($dataTable)
$sqlConnection.Close()
J'ai eu exactement le même problème et je crois que la raison est la suivante (a travaillé pour moi):
La connexion à la base de données n’est pas toujours fermée correctement, par exemple en cas d’erreur. S'il n'est pas fermé, la boucle while sera ignorée. Modifiez votre code comme suit:
$sqlConn.Open()
$cmd = $sqlConn.CreateCommand()
$cmd.CommandText ="SELECT * from user"
$movedUserDetails = $cmd.ExecuteReader()
try
{
while ($movedUserDetails.Read())
{
"[0] : " + $movedUserDetails.GetValue(0)
}
}
catch
{
#log error
}
finally
{
$sqlConn.Close()
}
L'instruction finally est toujours exécutée et garantit que la connexion est correctement fermée.
J'ai essayé votre code et cela a fonctionné. Peut-être que vous pouvez essayer avec une SqlDataAdapter
. J'ai créé ce module Powershell pour récupérer des enregistrements avec SQL. Il ne m'a jamais manqué
function Invoke-SqlSelect
{
[CmdletBinding()]
Param
(
[ValidateNotNullOrEmpty()]
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[string] $SqlServer,
[Parameter(ValueFromPipeline=$True,Mandatory=$False)]
[string] $Database = "master",
[ValidateNotNullOrEmpty()]
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[string] $SqlStatement
)
$ErrorActionPreference = "Stop"
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server=$SqlServer;Database=$Database;Integrated Security=True"
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$sqlCmd.CommandText = $SqlStatement
$sqlCmd.Connection = $sqlConnection
$sqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$sqlAdapter.SelectCommand = $sqlCmd
$dataTable = New-Object System.Data.DataTable
try
{
$sqlConnection.Open()
$sqlOutput = $sqlAdapter.Fill($dataTable)
Write-Output -Verbose $sqlOutput
$sqlConnection.Close()
$sqlConnection.Dispose()
}
catch
{
Write-Output -Verbose "Error executing SQL on database [$Database] on server [$SqlServer]. Statement: `r`n$SqlStatement"
return $null
}
if ($dataTable) { return ,$dataTable } else { return $null }
}