如何从PowerShell运行SQL Server查询?

147 sql powershell

有没有办法在本地计算机上使用Powershell在SQL Server上执行任意查询?

Chr*_*son 152

对于其他只需要库存.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

}
Run Code Online (Sandbox Code Playgroud)

我一直在使用这么长时间我不知道是谁编写了哪些部分,但这是从其他的例子中提炼出来的,但是简化为清楚,只需要没有额外的依赖关系或功能.

我经常使用和分享这个,我把它变成了GitHub上的一个脚本模块,这样你现在可以进入你的模块目录并执行git clone https://github.com/ChrisMagnuson/InvokeSQL,从那时起,当你去使用它时,将自动加载invoke-sql(假设你使用的是powershell v3或更高版本).

  • @AllTradesJack Google Sql Injection.Invoke-Sql命令无法包含与命令文本分开的参数.这几乎可以保证你使用字符串连接来构建查询,这是一个很大的禁忌. (4认同)
  • @Maslow我不能肯定地说,我知道在不处理对象的情况下可以正常工作,但是如果您有单个powershell.exe进程,它将在数周内多次调用此命令而不关闭,则最终可能是个问题,但是您将不得不测试。 (2认同)
  • 对我来说效果很好。对于任何想知道的人来说,要处理一个对象,只需添加 `$connection.dispose()` 等。我不知道它是否有任何区别 (2认同)

man*_*lds 98

您可以使用Invoke-Sqlcmdcmdlet

Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"
Run Code Online (Sandbox Code Playgroud)

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

  • 有人应该提一下,如果你在sql server的上下文中,这可能会很棒,但如果你使用你的工作站则不是很多...... (22认同)
  • 您可以在安装SQL Server客户端工具(SSMS)的任何位置运行此命令.它可以在任何工作站上正常运行,无论它是否正在运行SQL Server. (10认同)
  • 使用以下导入使cmdlet可用:`Import-Module"sqlps"-DisableNameChecking` (3认同)
  • Invoke-SqlCmd是奇特的边缘情况和行为不一致的噩梦。为什么有时会输出列而不是其他时间?我的错误信息在哪里?为什么在一台计算机上或不在另一台计算机上?如何安装?每个问题的答案都比最后一个答案差。 (2认同)
  • 如果您正在编写脚本来自动执行一些本来要自己构建和发出的查询,那么“Invoke-Sqlcmd”就很好,但由于它不支持参数,因此对于接受来自不受信任源的输入的任何内容来说,这是一个非常糟糕的主意。您可能认为“-Variables”选项可以让您防止 SQL 注入,但事实并非如此。请参阅http://www.cjsomer.com/2015-10-13-running-parameterized-queries-against-sql-server-using-powershell/。 (2认同)

dmc*_*dmc 27

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

$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();
Run Code Online (Sandbox Code Playgroud)

据推测,您可以用它所代替的不同TSQL语句替换它dbcc freeproccache.


mco*_*ien 24

此函数将作为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
}
Run Code Online (Sandbox Code Playgroud)

  • 可能没有太大的区别,但SqlDataReaders通常是首选,因为它们消耗的资源更少.这不太可能与此相关,但很高兴获得真实对象而不是可以在foreach和where子句中使用的数据表,而不必担心数据源. (2认同)

arn*_*nav 11

Invoke-Sqlcmd -Query "sp_who" -ServerInstance . -QueryTimeout 3
Run Code Online (Sandbox Code Playgroud)


Aar*_*sen 9

没有内置的"PowerShell"方式来运行SQL查询.如果安装了SQL Server工具,则会获得Invoke-SqlCmd cmdlet.

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


小智 8

如果您想在本地计算机上而不是在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
Run Code Online (Sandbox Code Playgroud)

只需填写$ ServerName,$ DatabaseName和$ Query变量,你应该好好去.

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