TransactSQL to run another TransactSQL script

后端 未结 6 872
逝去的感伤
逝去的感伤 2020-12-01 03:19

I have 10 transact SQL scripts that each create a table and fill it with data.

I am attempting to create 1 master sql script that will run each of the 10 other scrip

相关标签:
6条回答
  • 2020-12-01 03:50

    Assuming you want to keep the 10 scripts in their own individual files, I would say the easiest way to do what you want would be to create a batch file that executes osql.exe to execute the 10 scripts in the order you want.

    0 讨论(0)
  • 2020-12-01 03:54

    Or just use openrowset to read your script into a variable and execute it:

    DECLARE @SQL varchar(MAX)
    SELECT @SQL = BulkColumn
    FROM OPENROWSET
        (   BULK 'MeinPfad\MeinSkript.sql'
        ,   SINGLE_BLOB ) AS MYTABLE
    
    --PRINT @sql
    EXEC (@sql)
    
    0 讨论(0)
  • 2020-12-01 03:56

    Try this if you are trying to execute a .sql file in SSMS:

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

    note: for this to run turn on sql command mode (Query > SQLCMD Mode)

    If these are scripts you run fairly often you might consider dropping them in a stored proc and running them that way...

    You can also do it through sqlcmd (which I believe is more common):

    sqlcmd -S serverName\instanceName -i C:\Scripts\Script1.sql
    
    0 讨论(0)
  • 2020-12-01 03:59

    The simplest way would be to make your scripts stored procedures, and to call (via the EXECUTE command) each procedure in turn from a central procedure. This is ideal if you're going to run the exact same script(s) over and over again (or the same script with different parameters passed in).

    If your scripts are .sql (or any kind of text) file, as @Abe Miesller says (upvoted) you can run them from within SSMS via the :r command, when SQLCMD mode is enabled. You would have to know and script the exact file path and name. This cannot be done from within a stored procedure.

    A last alternative, usable with "known" file names and necessary for arbitrary file names (say, all files currently loaded in a subfolder) is to leverage the power of extended procedure XP_CMDSHELL. Such solutions can get compelx pretty fast (use it to retrieve list of files, build and execute via xp_cmdshell a string calling SQLCMD for each file in turn, manage results and errors via output files, it goes on and on) so I'd only do this as a last resort.

    0 讨论(0)
  • 2020-12-01 04:00

    You can use osql or better yet the newer sqlcmd almost interchangeably. I am using osql in this example only because I happened to have a code sample sitting around but in production I am using sqlcmd. Here is a snipped of code out of a larger procedure I use to run update scripts against databases. They are ordered by major, minor, release, build as I name my scripts using that convention to track releases. You are obviously missing all of my error handing, the parts where I pull available scripts from the database, setup variables, etc but you may still find this snippet useful.

    The main part I like about using osql or sqlcmd is that you can run this code in ssms, or in a stored procedure (called on a scheduled basis maybe) or from a batch file. Very flexible.

    --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
    
    0 讨论(0)
  • 2020-12-01 04:02

    I find it useful to define a variable with the path, if I want to execute a set of scripts, say to run a test, something like: :setvar path "C:\code\branch-qa" :r $(path)\tables\client.sql :r $(path)\tables\item.sql :r $(path)\proc\clientreport.sql exec clientreport

    0 讨论(0)
提交回复
热议问题