Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在SSMS中以SQLCMD模式获取文件的相对路径?_Sql Server_Ssms_Sqlcmd - Fatal编程技术网

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
然而,我确实找到了一种方法来做到这一点。我承认这并不是实现这一点的最理想的方法,但是,它目前似乎是获得真正相对路径的唯一方法(考虑到在变量中设置路径本身并不是真正的“相对”)

因此,您可以做的是:

  • 执行DOS命令以查找todo_master.sql,并将该文件的路径存储在可从SSMS获取的文件夹中的文本文件中,这可能是因为该路径是硬编码路径,也可能是因为它使用的环境变量对DOS命令和SSMS中的SQLCMD模式都可用
  • 在该文件中存储路径时,将其存储为SQLCMD模式命令,该命令将变量设置为该路径
  • 使用
    :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文件中设置的路径

    • 执行
      CD C:\
      将从C:驱动器的根开始。这可能不是最有效的起点。如果SQL文件通常位于C:\Users{YourLogin}\Documents\Visual Studio 2013\Projects等区域,则只需更改
      CD
      命令以靠近目标,例如:

      !!CD C:\Users\{YourLogin}\Documents\Visual Studio 2013&用于。。。
      

    我自己也遇到过同样的问题,我希望我不是在说明显而易见的问题-为什么不打开一个Dos/Cmd或PowerShell实例,
    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