Transact SQL运行另一个Transact SQL脚本

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Transact SQL运行另一个Transact SQL脚本相关的知识,希望对你有一定的参考价值。

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

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

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

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

谢谢!

答案

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

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

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

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

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

sqlcmd -S serverName\instanceName -i C:\Scripts\Script1.sql
另一答案

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

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

最后一个替代方案,可用于“已知”文件名,对任意文件名(例如,当前在子文件夹中加载的所有文件)都是必需的,是利用扩展过程XP_CMDSHELL的强大功能。这样的解决方案可以很快得到compelx(用它来检索文件列表,通过xp_cmdshell构建和执行一个字符串,依次为每个文件调用SQLCMD,通过输出文件管理结果和错误,它一直在继续)所以我只会这是最后的手段。

另一答案

您可以使用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
另一答案

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

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

--PRINT @sql
EXEC (@sql)
另一答案

假设您想将10个脚本保存在各自的文件中,我想说最简单的方法就是创建一个批处理文件来执行osql.exe,按照您想要的顺序执行10个脚本。

以上是关于Transact SQL运行另一个Transact SQL脚本的主要内容,如果未能解决你的问题,请参考以下文章

@@ROWCOUNT (Transact-SQL)

DATEADD (Transact-SQL)

5.Transact-SQL编程

在Transact SQL中并行执行存储过程

数据库视频Transact—SQL语句

Transact-SQL 语法约定