使用SQLCMD在SQLServer執行多個指令碼

2021-08-27 07:37:14 字數 4463 閱讀 8217

作為dba,經常要用開發人員提供的sql指令碼來更新正式資料庫,但是乙個比較合理的開發流程,當提交指令碼給dba執行的時候,可能已經有幾百個sql檔案,並且有執行順序,如我現在工作的公司,十幾個客戶,每個客戶乙個庫,但是資料庫結構、儲存過程、檢視等都是一模一樣,每次執行指令碼(以下稱為公升級),如果有一百個指令碼,那麼就要按順序執行過千次,這種工作量可不是乙個人能承受得了的。

sqlcmd:

使用sqlcmd

實用工具,可以在命令提示符處、在

sqlcmd

模式下的

查詢編輯器

」中、在

windows

指令碼檔案中或者在

sql server

**作業的作業系統

(cmd.exe)

作業步驟中輸入

transact-sql

語句、系統過程和指令碼檔案。

此實用工具使用

odbc

執行transact-sql

批處理。(**於

msdn

)詳細語法可以到網上查詢,這裡就不貼出來。

sqlcmd

有乙個很重要的命令:

:r,記住,

sqlcmd

是大小寫敏感的。當

:r發現正在執行

sql指令碼,它會告訴

sqlcmd

把這個檔案所引用的檔案一併放入呼叫指令碼中。這將告訴你,停止目前的單個查詢。並重新調整查詢,把應該關聯的查詢放到適當的位置。另外,使用

:r命令在乙個批處理中執行多個指令碼,使得你可以定義乙個單獨的變數集,用於包含所有指令碼,但是不包含

go終結符。

從2005

以後引入

sqlcmd

,可以用於將來替代

osql

工具。如果你不熟悉

sqlcmd

,可以認為它是乙個能從作業系統執行

t-sql

命令和指令碼的命令列工具。

下面例子中,建立5個作用在testdb資料庫上有關聯的sql檔案。第乙個指令碼叫做create_db.sql,用於建立乙個叫做testdb的資料庫。這個指令碼包含了4個其他的指令碼(使用了:r命令。),用於生成其他表、表插入、索引建立和儲存過程的建立。乙個.bat檔案用於建立用來執行sqlcmd命令。

指令碼1:create_db.sql

/* script: create_db.sql */

/* 建立testdb資料庫 */

-- this is the main caller for each script

set nocount on

goprint '開始建立testdb資料庫'

if exists (select 1 from sys.databases where name = 'testdb')

drop database testdb

gocreate database testdb

go:on error exit

:r c:\scripts\create_tables.sql

:r c:\scripts\table_inserts.sql

:r c:\scripts\create_indexes.sql

:r c:\scripts\create_procedures.sql

print '建立完畢'

go

指令碼2:create_indexes.sql

/* 建立索引 */

print '開始建立索引'

gouse testdb

goif not exists ( select 1

from sys.indexes

where name = 'ix_employee_lastname' )

create index ix_employee_lastname on dbo.employee(lastname, firstname)

goif not exists ( select 1

from sys.indexes

where name = 'ix_timecard_employeeid' )

create index ix_timecard_employeeid on dbo.timecard(employeeid)

go

指令碼3:create_procedures.sql

/* 建立儲存過程 */

print '正在建立儲存過程'

gouse testdb

goif object_id('get_employee_timecards') is not null

drop procedure dbo.get_employee_timecards

gocreate procedure dbo.get_employee_timecards @employeeid int

as set nocount on

select *

from dbo.employee e

join dbo.timecard t on e.employeeid = t.employeeid

where e.employeeid = @employeeid

order by dateworked

go

指令碼4:create_tables.sql

/* 建立資料表 */

print '正在建立資料表 '

gouse testdb

goif object_id('employee') is not null

drop table dbo.employee

gocreate table dbo.employee

(employeeid int identity(1, 1)

not null

primary key ,

firstname varchar(50) ,

lastname varchar(50)

)goif object_id('timecard') is not null

drop table dbo.timecard

gocreate table dbo.timecard

(timecardid int identity(1, 1)

not null

primary key ,

employeeid int not null ,

hoursworked tinyint not null ,

hourlyrate money not null ,

dateworked datetime not null

)godeclare @total_tables int

set @total_tables = 2

指令碼5:table_inserts.sql

/* 插入表資料 */

print 'total tables created = ' + cast(@total_tables as varchar)

goprint '正在插入資料到表 employee'

gouse testdb

goinsert into dbo.employee

( firstname, lastname )

select 'john' ,

'doe'

goinsert into dbo.employee

( firstname, lastname )

select 'jane' ,

'doe'

goinsert into dbo.employee

( firstname, lastname )

select 'jeff' ,

'doe'

go

sqlcmd -e -dmaster -ic:\scripts\create_db.sql

pause

雙擊檔案可以看到:

在執行前,是沒有testdb:

執行中:

執行後,該建立的東西都建立出來了:

由於執行的順序已經在指令碼1中定義好,所以直接執行即可,並且執行成功。

根據個人經驗,還是開發乙個批量執行工具會比較好,這個方法在少量指令碼的時候可以選用。

使用SQLCMD在SQLServer執行多個指令碼

作為dba,經常要用開發人員提供的sql指令碼來更新正式資料庫,但是乙個比較合理的開發流程,當提交指令碼給dba執行的時候,可能已經有幾百個sql檔案,並且有執行順序,如我現在工作的公司,十幾個客戶,每個客戶乙個庫,但是資料庫結構 儲存過程 檢視等都是一模一樣,每次執行指令碼 以下稱為公升級 如果有...

使用sqlcmd命令

今天剛知道ms sql 2005自帶sqlcmd命令,可以在命令列下操作sql server。用法 sqlcmd u 登入 id p 密碼 s 伺服器 h 主機名 e 可信連線 d 使用資料庫名稱 l 登入超時值 t 查詢超時值 h 標題 s 列分隔符 w 螢幕寬度 a 資料報大小 e 回顯輸入 i...

Sqlcmd使用 備查

今天學了下 sqlcmd 的簡單使用方法,這個工具是安裝 sqlserver 後附帶的乙個命令列查詢工具,sqlserver2005 express 下的目錄 c program files microsoft sql server 90 tools binn sqlcmd.exe 直接雙擊執行,就...