我有一个调用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的值,任何想法?
答案 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变量仍然可以正确替换。