sql-Transact SQL运行另一个Transact SQL脚本

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

我试图创建1个主SQL脚本,这些脚本将运行其他10个脚本。

TSQL / TRANSACTSQL是否可以通过Microsoft SQL Server 2008从当前tsql脚本中执行另一个tsql脚本?

它旨在通过SQL Server Management Studio(SSMS)运行。

谢谢!

Steve Stedman asked 2019-11-08T08:47:48Z
5个解决方案
92 votes

如果要在SSMS中执行.sql文件,请尝试以下方法:

:r C:\Scripts\Script1.sql
:r C:\Scripts\Script2.sql
:r C:\Scripts\Script3.sql
...

注意:要运行此命令,请打开sql命令模式(“查询”>“ SQLCMD模式”)

如果这些是您经常运行的脚本,则可以考虑将其放入存储的proc中并以这种方式运行...

您也可以通过sqlcmd(我相信这是更常见的)来做到这一点:

sqlcmd -S serverName\instanceName -i C:\Scripts\Script1.sql
Abe Miessler answered 2019-11-08T09:00:08Z
6 votes

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

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

--PRINT @sql
EXEC (@sql)
Pesche Helfer answered 2019-11-08T09:00:38Z
5 votes

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

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

最后一种替代方法是使用扩展过程XP_CMDSHELL的功能,可与“已知”文件名一起使用,并且对于任意文件名(例如,子文件夹中当前加载的所有文件)都必需使用。 文件列表,通过xp_cmdshell生成并执行一个字符串,依次为每个文件调用SQLCMD,通过输出文件管理结果和错误,它会不断运行),所以我只能做为最后的选择。

Philip Kelley answered 2019-11-08T09:01:21Z
5 votes

您可以互换使用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
Shane Delmore answered 2019-11-08T09:01:54Z
2 votes

假设您想将这10个脚本保存在各自的文件中,那么我想说,最简单的方法是创建一个批处理文件,该文件执行osql.exe以所需的顺序执行这10个脚本。

Russell McClure answered 2019-11-08T09:02:18Z
translate from https://stackoverflow.com:/questions/5237198/transactsql-to-run-another-transactsql-script