如何使用PowerShell执行.sql文件?

80

我有一个.sql文件。我试图通过Powershell脚本传递连接字符串细节并调用一个.sql文件。

我正在搜索与Invoke-sqlcmd相关的cmdlet。当我尝试查找与SQL对应的模块时,我没有在我的计算机上找到任何模块。

我需要在我的计算机上安装任何东西(计算机已经安装了SQL Server Management Studio 2008 R2)来获取模块吗?还是有任何简单的方法可以使用Powershell执行.sql文件?

7个回答

97

尝试查看 SQL snap-ins 是否存在:

get-pssnapin -Registered

Name        : SqlServerCmdletSnapin100
PSVersion   : 2.0
Description : This is a PowerShell snap-in that includes various SQL Server cmdlets.

Name        : SqlServerProviderSnapin100
PSVersion   : 2.0
Description : SQL Server Provider
如果是这样。
Add-PSSnapin SqlServerCmdletSnapin100 # here lives Invoke-SqlCmd
Add-PSSnapin SqlServerProviderSnapin100

然后你可以这样做:

invoke-sqlcmd -inputfile "c:\mysqlfile.sql" -serverinstance "servername\serverinstance" -database "mydatabase" # the parameter -database can be omitted based on what your sql script does.

6
针对 SQL Server 2012,需要使用 SqlServerCmdletSnapin110 和 SqlServerProviderSnapin110 进行注册。 - M.C.Rohith
2
只是提醒一下,我相信很多人会遇到这个问题。在较新的SQL版本中,它们有sqlps。您可以将Import-Module“sqlps” -DisableNameChecking添加到您的脚本中。 - workabyte
1
@workabyte 你看过下面这个答案了吗:https://dev59.com/M2gv5IYBdhLWcg3wCcaZ#10923160 ?? ;) - CB.
@CB。哈哈不是的,这就是为什么我在这里放置了评论,这个答案在顶部并且有很多票数,所以我添加了评论,让人们看到它,而不像下面的答案。谢谢你指出来,笑死我了。 - workabyte
1
提示:对于较新版本的PowerShell,您可能想尝试使用Import-Module SQLPSGet-Module -List | ? Name -eq sqlps来查看是否有一个或多个可导入的SQLPS模块。 - qJake
显示剩余2条评论

45

以下是从MSDN文档“导入SQLPS模块”中引用的内容:

从PowerShell管理SQL Server的推荐方式是将sqlps模块导入到Windows PowerShell 2.0环境中。

因此,您可以使用Christian详细介绍的Add-PSSnapin方法,但了解推荐的sqlps模块方法也很有用。

最简单的情况假设您拥有SQL Server 2012:sqlps已包含在安装中,因此您只需像加载其他模块一样(通常是在您的配置文件中)通过Import-Module sqlps来加载该模块。您可以使用Get-Module -ListAvailable检查系统上是否可用该模块。

如果您没有SQL Server 2012,则只需将sqlps模块下载到模块目录中,以便Get-Module/Import-Module找到它。奇怪的是,Microsoft并没有提供该模块的下载!不过,Chad Miller已经打包好所需的文件,并提供该模块的下载。将其解压到...Documents\WindowsPowerShell\Modules目录下,然后进行导入。

值得注意的是,模块化方法和快速插件方法并不相同。如果您加载了快速插件,然后运行Get-PSSnapin不要使用-Registered参数,只显示已加载的内容),则会看到SQL快捷方式。另一方面,如果您加载了sqlps模块,则Get-PSSnapin将不会显示已加载的快捷方式,因此,那些仅通过检查快速插件来测试Invoke-Sqlcmd cmdlet的各种博客文章可能会给出虚假的负结果。 2012.10.06更新 有关sqlps模块与sqlps迷你shell与SQL Server快捷方式的完整故事,请参阅我在Simple-Talk.com上最近发布的两部分迷你系列《SQL Server开发人员和数据库管理员的实用PowerShell》,根据一位读者的评论,我已经成功“消除”了这个问题。 :-)

3
请注意,您现在可以从微软的网站下载SQLPS模块,其中包含PowerShellTools.msi的x86和x64版本。请查看以下链接:http://www.microsoft.com/en-us/download/details.aspx?id=35580。 - thomasb
正确的命令是 Get-Module -ListAvailable,而不是 Get-Module -ListAvalable - wut-excel
要在SSMS 17或更高版本中使用PowerShell,请使用“Install-Module -Name SqlServer”从PowerShell Gallery安装它。 - LeBleu

7
if(Test-Path "C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS") { #Sql Server 2012
    Import-Module SqlPs -DisableNameChecking
    C: # Switch back from SqlServer
} else { #Sql Server 2008
    Add-PSSnapin SqlServerCmdletSnapin100 # here live Invoke-SqlCmd
}

Invoke-Sqlcmd -InputFile "MySqlScript.sql" -ServerInstance "Database name" -ErrorAction 'Stop' -Verbose -QueryTimeout 1800 # 30min

5
这里提供了一种轻量级的方法来编写简单脚本,无需额外工具/设置/PowerShell插件。
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = $connectionStringGoesHere
$conn.Open()
$content = Get-Content $scriptFileNameGoesHere
$cmds = New-Object System.Collections.ArrayList
$cmd = ""
$content | foreach {
    if ($_.Trim() -eq "GO") { $cmds.Add($cmd); $cmd = "" } 
    else { $cmd =  $cmd + $_ +"`r`n" }
}
$cmds | foreach {
    $sc = New-Object System.Data.SqlClient.SqlCommand 
    $sc.CommandText = $_
    $sc.Connection = $conn
    $sc.ExecuteNonQuery()
}

5

这里有一个我在PowerShell配置文件中使用的函数,用于加载SQL Snapins:

function Load-SQL-Server-Snap-Ins
{
    try 
    {
        $sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"

        if (!(Test-Path $sqlpsreg -ErrorAction "SilentlyContinue"))
        {
            throw "SQL Server Powershell is not installed yet (part of SQLServer installation)."
        }

        $item = Get-ItemProperty $sqlpsreg
        $sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)

        $assemblyList = @(
            "Microsoft.SqlServer.Smo",
            "Microsoft.SqlServer.SmoExtended",
            "Microsoft.SqlServer.Dmf",
            "Microsoft.SqlServer.WmiEnum",
            "Microsoft.SqlServer.SqlWmiManagement",
            "Microsoft.SqlServer.ConnectionInfo ",
            "Microsoft.SqlServer.Management.RegisteredServers",
            "Microsoft.SqlServer.Management.Sdk.Sfc",
            "Microsoft.SqlServer.SqlEnum",
            "Microsoft.SqlServer.RegSvrEnum",
            "Microsoft.SqlServer.ServiceBrokerEnum",
            "Microsoft.SqlServer.ConnectionInfoExtended",
            "Microsoft.SqlServer.Management.Collector",
            "Microsoft.SqlServer.Management.CollectorEnum"
        )

        foreach ($assembly in $assemblyList)
        { 
            $assembly = [System.Reflection.Assembly]::LoadWithPartialName($assembly) 
            if ($assembly -eq $null)
                { Write-Host "`t`t($MyInvocation.InvocationName): Could not load $assembly" }
        }

        Set-Variable -scope Global -name SqlServerMaximumChildItems -Value 0
        Set-Variable -scope Global -name SqlServerConnectionTimeout -Value 30
        Set-Variable -scope Global -name SqlServerIncludeSystemObjects -Value $false
        Set-Variable -scope Global -name SqlServerMaximumTabCompletion -Value 1000

        Push-Location

         if ((Get-PSSnapin -Name SqlServerProviderSnapin100 -ErrorAction SilentlyContinue) -eq $null) 
        { 
            cd $sqlpsPath

            Add-PsSnapin SqlServerProviderSnapin100 -ErrorAction Stop
            Add-PsSnapin SqlServerCmdletSnapin100 -ErrorAction Stop
            Update-TypeData -PrependPath SQLProvider.Types.ps1xml
            Update-FormatData -PrependPath SQLProvider.Format.ps1xml
        }
    } 

    catch 
    {
        Write-Host "`t`t$($MyInvocation.InvocationName): $_" 
    }

    finally
    {
        Pop-Location
    }
}

1
使用2008 Server 2008和2008 R2。
Add-PSSnapin -Name SqlServerCmdletSnapin100, SqlServerProviderSnapin100

与2012年和2014年相关

Push-Location
Import-Module -Name SQLPS -DisableNameChecking
Pop-Location

0

Invoke-Sqlcmd -Database MyDatabase -Query "exec dbo.sp_executesql N'$(Get-Content "c:\my.sql")'"

Invoke-Sqlcmd -Database MyDatabase -Query "exec dbo.sp_executesql N'$(Get-Content "c:\my.sql")'"


此函数会出错,如果文件中的SQL包含引号。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接