Sql server 如何在SSMS中以SQLCMD模式获取文件的相对路径?
我有下面的主脚本,它创建表,插入一些数据,然后创建存储过程Sql server 如何在SSMS中以SQLCMD模式获取文件的相对路径?,sql-server,ssms,sqlcmd,Sql Server,Ssms,Sqlcmd,我有下面的主脚本,它创建表,插入一些数据,然后创建存储过程 --todo_master.sql use master go :r todo_create_ddl.sql :r todo_create_dml.sql :r todo_create_sprocs.sql go 但是,即使todo_master.sql与其他三个脚本位于同一路径中,它也无法找到这三个脚本 我得到以下错误: A fatal scripting error occurred. The file specified f
--todo_master.sql
use master
go
:r todo_create_ddl.sql
:r todo_create_dml.sql
:r todo_create_sprocs.sql
go
但是,即使todo_master.sql与其他三个脚本位于同一路径中,它也无法找到这三个脚本
我得到以下错误:
A fatal scripting error occurred.
The file specified for :r command was not found.
如果我像下面这样提供完整的路径,这些文件将按预期的方式找到并执行
“C:\Docs and Settings\user\My Docs\SSMS\Projects\todo\u create\u ddl.sql”
我可能会错过什么
编辑 根据Jason的建议,我尝试了这个方法,但仍然得到相同的错误:
use master
go
:setvar path "C:\Documents and Settings\user\My Documents\SQL Server Management Studio\Projects"
:setvar ddl "todo_create_ddl.sql"
:setvar dml "todo_create_dml.sql"
:setvar sprocs "todo_create_sprocs.sql"
:r $(path)$(ddl)
:r $(path)$(dml)
:r $(path)$(sprocs)
go
您可以通过使用sqlcmd
setvar
选项将路径分配给变量来解决此问题。然后在:r
调用中使用该变量,如:
:setvar path "c:\some path"
:r $(path)\myfile.sql
此链接有一个更深入的示例:
有了它,您可以删除setvar行,并使用以下命令从命令行传入该行:
Sqlcmd /Sserver /E -ddatabase -iInputfilename -oOutputfilename -v path=c:\somepath
这将解决脚本不从调用第一个SQL脚本的目录运行的问题 我发现,这将是最好的:
:setvar path C:\"some path"
:r $(path)\myfile.sql
您必须将语句加上引号,但不能将整个语句加上空格。这就是为什么您可以执行
C:\“some path”
我意识到这很旧,但我注意到您编辑的代码中有一个错误:您需要在路径和脚本名称之间包含一个反斜杠
:r $(path)\$(ddl)
:r $(path)\$(dml)
:r $(path)\$(sprocs)
在SSMS中获取相对路径并不是那么简单,因为您没有执行脚本;SSMS已将脚本加载到内存中,并正在执行其文本。因此,当前目录/文件夹是默认的进程启动文件夹。通过在SSMS中以SQLCMD模式运行以下命令,可以看到这一点:
!! PWD
然而,我确实找到了一种方法来做到这一点。我承认这并不是实现这一点的最理想的方法,但是,它目前似乎是获得真正相对路径的唯一方法(考虑到在变量中设置路径本身并不是真正的“相对”)
因此,您可以做的是:
:r
将该文本文件导入SSMS,它会将该变量设置为所需的路径!!CD C:\&对于('DIR/B/A-HS/S todo_master.sql')中的/F%B,执行ECHO:setvar mypath“%~dpB”>%TEMP%\relative_path.txt
:r$(临时)\relative\u path.txt
:r$(mypath)\todo\u create\u ddl.sql
去
:r$(mypath)\todo\u create\u dml.sql
去
:r$(mypath)\todo\u create\u sprocs.sql
去
注:
- 上述方法假设系统上只有一个文件名为todo\u master.sql。如果有多个文件具有该名称,则最后找到的文件将是relative_path.txt文件中设置的路径
- 执行
将从C:驱动器的根开始。这可能不是最有效的起点。如果SQL文件通常位于C:\Users{YourLogin}\Documents\Visual Studio 2013\Projects等区域,则只需更改CD C:\
命令以靠近目标,例如:CD
!!CD C:\Users\{YourLogin}\Documents\Visual Studio 2013&用于。。。
cd
到包含脚本的目录,然后从那里加载Management Studio
我的PowerShell设置中有此别名(您的路径可能不同):
然后,我将cd
复制到包含解决方案文件的文件夹中,然后执行此操作
Ssms mysolution.ssmssln
将批处理文件用作帮助程序 修改todo_master.sql以使用名为
mypath
的环境变量:
use master
go
:r $(mypath)\todo_create_ddl.sql
:r $(mypath)\todo_create_dml.sql
:r $(mypath)\todo_create_sprocs.sql
go
在批处理文件中todo_master.bat
/* set the environment variable to the current directory */
SET mypath=%cd%
/* run your sql command */
sqlcmd -i todo_master.sql
connect.microsoft.com中的相关链接谢谢您的建议。不幸的是,这对我不起作用。我已经更新了这个问题,加入了我根据你的建议尝试过的内容。到目前为止,我发现在文件夹路径中使用空格不起作用。我用没有空格的文件夹路径尝试了这个方法,发现它确实有效。所有这一切只是创建一个要执行的绝对路径,而不是原始问题所要求的。这不是一个可行的解决方案,因为需要相对路径,例如连续集成、连续交付等,这种方法需要为不同的环境编辑文件,或者为不同的环境调用具有唯一powershell参数的脚本。当然,但这是一个不同的解决方案。完全同意@CShark-让你想知道他们为什么要费心包括:r。如果唯一的方法是使用PS将路径作为变量传递给SQLCMD,那么我可以通过sql文件本身的名称来实现这一点,我不需要将变量传递给SQLCMD来让它运行运行脚本的脚本,我只需要使用PS来运行使用SQLCMD的脚本-根本不需要:r。感谢您的解决方案,一个小的调整是,如果路径包含空格,则需要包含for命令的delims选项。示例:
用于(…)中的“delims=;%B
/* set the environment variable to the current directory */
SET mypath=%cd%
/* run your sql command */
sqlcmd -i todo_master.sql