如何通过Powershell将参数传递给SQL脚本

时间:2014-04-02 12:22:39

标签: sql shell powershell

我有一个调用SQL脚本的Power-shell脚本。这当前有效,但在我的sql脚本中,我有一些硬编码参数,我想通过powershell传递给SQL脚本。

所以这是来自Power-shell脚本的剪辑

function ExecSqlScript([string] $scriptName)
{
$scriptFile = $script:currentDir + $scriptName
$sqlLog = $script:logFileDir + $scriptName + "_{0:yyyyMMdd_HHmmss}.log" -f (Get-Date)
$result = sqlcmd -S uk-ldn-dt270 -U sa -P passwordhere3! -i $scriptFile -b | Tee-Object -             filepath $sqlLog

 if ($result -like "*Msg *, Level *, State *" -Or $result -like "*Sqlcmd: Error:*") 
    {
    throw "SQL script " + $scriptFile + " failed: " + $result
    }   
}

try
{
    ExecSqlScript "restoreDatabase.sql"
}
catch
{
 //Some Error handling here
}

这是来自SQL

USE MASTER
GO
DECLARE @dbName varchar(255)
SET @dbName = 'HardCodedDatabaseName'

所以我想传递dbName的值,任何想法?

4 个答案:

答案 0 :(得分:9)

您可以利用sqlcmd的scripting variables。这些可以在脚本文件中使用,并标有$()。像这样,

-- Sql script file
use $(db);
select someting from somewhere;

调用sqlcmd时,请使用-v参数指定变量。像这样,

sqlcmd -S server\instance -E -v db ="MyDatabase" -i s.sql

修改

设置变量时请注意Sql语法。请考虑以下脚本:

DECLARE @dbName varchar(255)
SET @dbName = $(db)
select 'val' = @dbName

传递给Sql Server时,它看起来像是这样(Profiler在这里帮助):

use master;

DECLARE @dbName varchar(255)
SET @dbName = foo
select 'val' = @dbName

这显然是一种语法无效,因为SET @dbName = foo没有多大意义。该值应该在单引号内,如此,

sqlcmd -S server\instance -E -v db ="'foo'" -i s.sql

答案 1 :(得分:4)

以防其他人需要这样做......这是一个有效的例子。

Power Shell脚本:

sqlcmd -S uk-ldn-dt270 -U sa -P 1NetNasdf£! -v db = "'DatabaseNameHere'" -i $scriptFile -b | Tee-Object -filepath $sqlLog

注意-v开关分配变量

这是MS SQL:

USE MASTER
GO

if db_id($(db)) is null

BEGIN
    EXEC('
    RESTORE DATABASE ' + $(db) + '
    FROM DISK = ''D:\DB Backup\EmptyLiveV5.bak''
    WITH MOVE ''LiveV5_Data'' TO ''C:\Program Files (x86)\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\LiveV5_' + $(db) + '.MDF'',
    MOVE ''LiveV5_Log'' To ''C:\Program Files (x86)\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\LiveV5_' + $(db) + '_log.LDF'', REPLACE,
    STATS =10')
END

注意:您不必将脚本变量分配给这样的普通sql变量。

SET @dbName = $(db)

你可以在你的sql代码中使用它。 - 快乐的编码。

答案 2 :(得分:1)

这是一个使用不同 PowerShell 方法的完整示例。在这里,我使用了一个特定的脚本来重置本地数据库以创建一个干净的开发环境。

## Reset the Database
$resetScript= "C:\ResetSite\resetDatabases.sql"
Write-Host "Resetting the DB - Running $($resetScript)"
$connectionString = "Server = localhost; Database = 'master'; UID = myusername; PWD = mypassword"

# Create variables & params
$sqlCmdVariables = @(
    "Database=$($siteConfig.db_name)",
    "UserName=$($siteConfig.db_username)",
    "UserPassword=$($siteConfig.db_user_password)"
)
$sqlCmdParameters = @{
    InputFile = $resetScript
    QueryTimeout = 1800
    ConnectionString = $connectionString
    Variable = $sqlCmdVariables
}
# Invoke
Invoke-SqlCmd @sqlCmdParameters

.sql 文件然后使用传入的参数,与@nmbell 提到的方式相同。

-- Declare the vars
DECLARE @Database nvarchar(100), @UserName nvarchar(100), @UserPassword nvarchar(100)

-- Set the vars
SET @Database = '$(Database)' -- database name
SET @UserName = '$(UserName)' -- SQL login and database username
SET @UserPassword = '$(UserPassword)' -- login password

... more stuff here.. use the vars like normal

这部分源自 this blog post,但稍作修改以使用文件而不是内联查询。

答案 3 :(得分:0)

调整vonPryz的使用答案:

SET @dbName = '$(db)'

意味着您可以以更自然的形式从命令行传递参数

sqlcmd -S server\instance -E -v db ="foo" -i s.sql

SqlCmd变量仍然可以正确替换。