TransactSQL运行另一个TransactSQL脚本

Ste*_*man 57 sql t-sql sql-server sql-server-2008

我有10个transact SQL脚本,每个脚本创建一个表并用数据填充它.

我正在尝试创建一个主sql脚本,它将运行其他10个脚本中的每一个.

有没有办法用TSQL/TRANSACTSQL为Microsoft SQL Server 2008从当前的tsql脚本中执行另一个tsql脚本?

这旨在通过SQL Server Management Studio(SSMS)运行.

谢谢!

Abe*_*ler 93

如果您尝试在SSMS中执行.sql文件,请尝试此操作:

:r C:\Scripts\Script1.sql
:r C:\Scripts\Script2.sql
:r C:\Scripts\Script3.sql
...
Run Code Online (Sandbox Code Playgroud)

注意:为此运行打开sql命令模式(查询> SQLCMD模式)

如果这些是您经常运行的脚本,您可以考虑将它们放在存储过程中并以这种方式运行它们......

你也可以通过sqlcmd(我认为更常见)来做到这一点:

sqlcmd -S serverName\instanceName -i C:\Scripts\Script1.sql
Run Code Online (Sandbox Code Playgroud)

  • 注意:在SSMS中使用:r需要打开SQLCMD模式:查询菜单 - > SQLCMD模式. (37认同)
  • `:r`是做什么的?它在哪里记录?你能提供链接吗? (4认同)
  • 使用`:r`语法.得到`"解析时遇到了错误的语法:r`"使用`:r'c:\ some path\script.sql'`命令时出错.其他人说路径不应该有空格.但是在更改为`:r"c:\ some path\script.sql"`(注意路径包围着```````.与你在命令行中应该做的一样)一切正常.SSMS 2012. (4认同)
  • @Oded,请阅读:http://msdn.microsoft.com/en-us/library/ms174187.aspx`:r`导入并执行文件. (3认同)
  • 这个岩石!两天前我遇到了很大的需求,但找不到一个很好的例子.谢谢!注意:您的文件路径和文件名中不应包含空格以使其正常工作.另外,我使用的是":r"语法,而不是sqlcmd. (3认同)
  • 如果您正在调整一个或多个脚本,然后使用这个很棒的 :r 解决方案测试它们(谢谢 Abe Miessler!!!),需要注意一件事。这只是刺痛了我,但一旦你意识到这一点或读到这篇文章,就会很明显。如果您更改脚本并且不保存它,就像我们通常在不使用批处理 :r 解决方案时所做的那样,而是习惯于仅按 F5 来运行它,则 :r sqlcmd 语句将运行 .如果您没有保存当前 SSMS 会话内存中的内容,您会认为您的调整没有执行任何操作。希望这对某人有帮助。 (3认同)

phi*_*l_w 7

我发现如果我想执行一组脚本(例如运行测试),使用路径定义变量很有用,例如: :setvar path "C:\code\branch-qa" :r $(path)\tables\client.sql :r $(path)\tables\item.sql :r $(path)\proc\clientreport.sql exec clientreport


Pes*_*fer 6

或者只是使用openrowset将脚本读入变量并执行:

DECLARE @SQL varchar(MAX)
SELECT @SQL = BulkColumn
FROM OPENROWSET
    (   BULK 'MeinPfad\MeinSkript.sql'
    ,   SINGLE_BLOB ) AS MYTABLE

--PRINT @sql
EXEC (@sql)
Run Code Online (Sandbox Code Playgroud)

  • 这很好;但要注意的是,它仅适用于内容适合“varchar(MAX)”的文件。 (2认同)
  • SINGLE_CLOB 对我有用,SINGLE_BLOB 给了我一个语法错误 (2认同)

Phi*_*ley 5

最简单的方法是使脚本存储过程,并EXECUTE从中央过程依次调用(通过命令)每个过程。如果您要一遍又一遍地运行完全相同的脚本(或传入了不同参数的相同脚本),则这是理想的选择。

如果您的脚本是.sql(或任何类型的文本)文件,如@Abe Miesller所说(已批准),则在启用SQLCMD模式后,可以通过:r命令从SSMS中运行它们。您将必须知道并编写脚本的确切文件路径和名称。这不能从存储过程中完成。

最后一种替代方法是利用扩展过程的功能,该替代方法可用于“已知”文件名,并且对于任意文件名(例如,当前在子文件夹中加载的所有文件)都是必需的XP_CMDSHELL。这样的解决方案可以非常快速地获得compelx(使用它来检索文件列表,通过xp_cmdshell生成并执行一个依次为每个文件调用SQLCMD的字符串,通过输出文件管理结果和错误,等等),我只想不得已而为之。


Sha*_*ore 5

您可以互换使用osql或更新更好的sqlcmd。我在此示例中使用osql仅仅是因为我碰巧有一个代码示例,但是在生产环境中我正在使用sqlcmd。这是我用来对数据库运行更新脚本的较大过程的一部分代码。它们按照主要,次要,发布,构建的顺序排序,正如我使用该约定来跟踪发布的命名脚本一样。您显然错过了我所有的错误处理,从数据库中提取可用脚本的部分,设置变量等,但是您可能仍然觉得此片段有用。

我喜欢使用osql或sqlcmd的主要部分是,您可以在ssms中或在存储过程(可能按计划调用)中或从批处理文件中运行此代码。非常灵活。

--Use cursor to run upgrade scripts
DECLARE OSQL_cursor CURSOR
READ_ONLY
FOR SELECT FileName 
FROM #Scripts
ORDER BY Major, Minor, Release, Build

OPEN OSQL_cursor

FETCH NEXT FROM OSQL_cursor INTO @name
WHILE (@@fetch_status <> -1)
BEGIN
    IF ((@@fetch_status <> -2) AND (@result = 0))
    BEGIN
        SET @CommandString = 'osql -S ' + @@ServerName + ' -E -n -b -d ' + @DbName + ' -i "' + @Dir + @name + '"'
        EXEC @result = master.dbo.xp_cmdshell @CommandString, NO_OUTPUT
        IF (@result = 0)
        BEGIN
            SET @Seconds = DATEDIFF(s, @LastTime, GETDATE())
            SET @Minutes = @Seconds / 60
            SET @Seconds = @Seconds - (@Minutes * 60)
            PRINT 'Successfully applied ' + @name + ' in ' + cast(@Minutes as varchar) 
                + ' minutes ' + cast(@Seconds as varchar) + ' seconds.'
            SET @LastTime = GETDATE()
        END
        ELSE
        BEGIN
            SET @errMessage = 'Error applying ' + @name + '! The database is in an unknown state and the schema may not match the version.'
            SET @errMessage = @errMessage + char(13) + 'To find the error restore the database to version ' + @StartingVersion
            SET @errMessage = @errMessage + ', set @UpToVersion = the last version successfully applied, then run ' + @name
            SET @errMessage = @errMessage + ' manually in Query Analyzer.'  
        END
        IF @name = (@UpToVersion + '.sql')
            GOTO CleanUpCursor --Quit if the final script specified has been run.
    END
    FETCH ENDT FROM OSQL_cursor INTO @name
END
Run Code Online (Sandbox Code Playgroud)