繁体   English   中英

如何从 PowerShell 运行 SQL 服务器查询?

[英]How do you run a SQL Server query from PowerShell?

有没有办法在我的本地机器上使用 Powershell 在 SQL 服务器上执行任意查询?

对于需要仅使用股票 .NET 和 PowerShell(未安装其他 SQL 工具)执行此操作的其他人,这是我使用的功能:

function Invoke-SQL {
    param(
        [string] $dataSource = ".\SQLEXPRESS",
        [string] $database = "MasterData",
        [string] $sqlCommand = $(throw "Please specify a query.")
      )

    $connectionString = "Data Source=$dataSource; " +
            "Integrated Security=SSPI; " +
            "Initial Catalog=$database"

    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
    $connection.Open()
    
    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataSet) | Out-Null
    
    $connection.Close()
    $dataSet.Tables

}

我一直在使用这个,我不知道谁写了哪些部分。 这是从其他人的例子中提炼出来的,但简化为清晰,正是需要的,没有额外的依赖项或功能。

我经常使用和分享这个,我已经把它变成了GitHub 上的一个脚本模块,这样你现在就可以转到你的模块目录并执行git clone https://github.com/ChrisMagnuson/InvokeSQL并从那时开始调用- sql 将在您使用时自动加载(假设您使用 PowerShell v3 或更高版本)。

您可以使用Invoke-Sqlcmd cmdlet

Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"

http://technet.microsoft.com/en-us/library/cc281720.aspx

此函数将查询结果作为 powershell 对象数组返回,以便您可以在过滤器中使用它们并轻松访问列:

function sql($sqlText, $database = "master", $server = ".")
{
    $connection = new-object System.Data.SqlClient.SQLConnection("Data Source=$server;Integrated Security=SSPI;Initial Catalog=$database");
    $cmd = new-object System.Data.SqlClient.SqlCommand($sqlText, $connection);

    $connection.Open();
    $reader = $cmd.ExecuteReader()

    $results = @()
    while ($reader.Read())
    {
        $row = @{}
        for ($i = 0; $i -lt $reader.FieldCount; $i++)
        {
            $row[$reader.GetName($i)] = $reader.GetValue($i)
        }
        $results += new-object psobject -property $row            
    }
    $connection.Close();

    $results
}

这是我在这个博客上找到的一个例子。

$cn2 = new-object system.data.SqlClient.SQLConnection("Data Source=machine1;Integrated Security=SSPI;Initial Catalog=master");
$cmd = new-object system.data.sqlclient.sqlcommand("dbcc freeproccache", $cn2);
$cn2.Open();
if ($cmd.ExecuteNonQuery() -ne -1)
{
    echo "Failed";
}
$cn2.Close();

大概你可以替换一个不同的 TSQL 语句,它说dbcc freeproccache

如果您想在本地计算机上而不是在 SQL 服务器的上下文中执行此操作,那么我将使用以下内容。 这是我们在我公司使用的。

$ServerName = "_ServerName_"
$DatabaseName = "_DatabaseName_"
$Query = "SELECT * FROM Table WHERE Column = ''"

#Timeout parameters
$QueryTimeout = 120
$ConnectionTimeout = 30

#Action of connecting to the Database and executing the query and returning results if there were any.
$conn=New-Object System.Data.SqlClient.SQLConnection
$ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerName,$DatabaseName,$ConnectionTimeout
$conn.ConnectionString=$ConnectionString
$conn.Open()
$cmd=New-Object system.Data.SqlClient.SqlCommand($Query,$conn)
$cmd.CommandTimeout=$QueryTimeout
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[void]$da.fill($ds)
$conn.Close()
$ds.Tables

只需填写$ServerName$DatabaseName$Query变量就可以了。

我不确定我们最初是如何发现这一点的,但这里有一些非常相似的东西

Invoke-Sqlcmd -Query "sp_who" -ServerInstance . -QueryTimeout 3

没有运行 SQL 查询的内置“PowerShell”方式。 如果您安装了SQL Server 工具,您将获得一个Invoke-SqlCmd cmdlet。

由于 PowerShell 是基于 .NET 构建的,因此您可以使用ADO.NET API来运行您的查询。

为了避免使用 varchar 参数进行 SQL 注入,您可以使用

function sqlExecuteRead($connectionString, $sqlCommand, $pars) {

    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $connection.Open()
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand, $connection)

    if ($pars -and $pars.Keys) {
        foreach($key in $pars.keys) {
            # avoid injection in varchar parameters
            $par = $command.Parameters.Add("@$key", [system.data.SqlDbType]::VarChar, 512);
            $par.Value = $pars[$key];
        }
    }

    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataset) | Out-Null
    $connection.Close()
    return $dataset.tables[0].rows

}

$connectionString = "connectionstringHere"
$sql = "select top 10 Message, TimeStamp, Level from dbo.log " +
    "where Message = @MSG and Level like @LEVEL"
$pars = @{
    MSG = 'this is a test from powershell'
    LEVEL = 'aaa%'
};
sqlExecuteRead $connectionString $sql $pars

您甚至可以根据需要格式化字符串并传递参数。

case "ADDSQLSERVERUSER":
    //0 = coprorateName;
    //1 = user password
    //2 = servername
    command = @"$sqlQuery = Use JazzUWS_'{0}' 
                Create login UWSUser_'{0}' with password='{1}';
                Create user UWSUser_'{0}' for login UWSUser_'{0}';
                Grant Execute to UWSUser_'{0}';

                Use ReportSvrUWS_'{0}' 
                Create user UWSUser_'{0}' for login UWSUser_'{0}';
                Grant Execute to UWSUser_'{0}';

                Invoke-Sqlcmd -Query $sqlQuery -ServerInstance '{2}'";
    break;

您可以使用最好的 SQL 服务器模块:DBATOOLS。 您还可以从对多个 sql 实例运行查询中受益。

Install-Module dbatools -Scope CurrentUser

$sql = 'SQL1','SQL1\INSTANCE1','SQL2'
$query = "SELECT 'This query would run on all SQL instances'"

Invoke-DbaQuery -SqlInstance $sqlinstances -Query $query -AppendServerInstance

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM