相信,很多網友都有用SQL介面產生指令碼再執行的習慣,今天在CSDN看到一個案例,好大的風險-_-!!!
本樣本是將一個表的列由datetime變成char型:
step 1 產生資料庫:
USE masterGO--建立測試數庫CREATE DATABASE [DB_TEST] ON PRIMARY ( NAME = N'DB_TEST', FILENAME = N'D:\SQL2008\Data\DB_TEST.mdf' , SIZE = 512MB , FILEGROWTH = 1024KB, MAXSIZE = 524288KB)LOG ON ( NAME = N'DB_TEST_log', FILENAME = N'D:\SQL2008\Log\DB_TEST_log.ldf' , SIZE = 1024KB , FILEGROWTH = 1024KB )GO
step 2 產生表,並產生測試資料
USE [DB_TEST]GOCREATE TABLE TB_TEST (ID INT IDENTITY(1,1) PRIMARY KEY,B DATETIME)GOINSERT INTO TB_TEST SELECT GETDATE()GO 100000
step 3 通過介面修改列類型,然後產生指令碼:
產生的指令碼為:
BEGIN TRANSACTIONSET QUOTED_IDENTIFIER ONSET ARITHABORT ONSET NUMERIC_ROUNDABORT OFFSET CONCAT_NULL_YIELDS_NULL ONSET ANSI_NULLS ONSET ANSI_PADDING ONSET ANSI_WARNINGS ONCOMMITBEGIN TRANSACTIONGOCREATE TABLE dbo.Tmp_TB_TEST ( ID int NOT NULL IDENTITY (1, 1), B char(7000) NULL ) ON [PRIMARY]GOALTER TABLE dbo.Tmp_TB_TEST SET (LOCK_ESCALATION = TABLE)GOSET IDENTITY_INSERT dbo.Tmp_TB_TEST ONGOIF EXISTS(SELECT * FROM dbo.TB_TEST) EXEC('INSERT INTO dbo.Tmp_TB_TEST (ID, B) SELECT ID, CONVERT(char(7000), B) FROM dbo.TB_TEST WITH (HOLDLOCK TABLOCKX)')GOSET IDENTITY_INSERT dbo.Tmp_TB_TEST OFFGODROP TABLE dbo.TB_TESTGOEXECUTE sp_rename N'dbo.Tmp_TB_TEST', N'TB_TEST', 'OBJECT' GOALTER TABLE dbo.TB_TEST ADD CONSTRAINT PK__TB_TEST__3214EC277F60ED59 PRIMARY KEY CLUSTERED ( ID ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]GOCOMMIT
step 4 然後把產生的指令碼拿到ssms query裡去執行,悲懼了:
文字為:
Msg 1105, Level 17, State 2, Line 1
無法為資料庫 'DB_TEST' 中的對象 'dbo.Tmp_TB_TEST' 分配空間,因為 'PRIMARY' 檔案組已滿。請刪除不需要的檔案、刪除檔案組中的對象、將其他檔案添加到檔案組或為檔案組中的現有檔案啟用自動成長,以便增加可用磁碟空間。
Msg 1088, Level 16, State 11, Line 1
找不到對象 "dbo.Tmp_TB_TEST",因為它不存在或者您沒有所需的許可權。
Msg 15248, Level 11, State 1, Procedure sp_rename, Line 321
參數 @objname 不明確或所聲明的 @objtype (OBJECT)有誤。
Msg 4902, Level 16, State 1, Line 1
找不到對象 "dbo.TB_TEST",因為它不存在或者您沒有所需的許可權。
Msg 3902, Level 16, State 1, Line 1
COMMIT TRANSACTION 請求沒有對應的 BEGIN TRANSACTION。
step 5 你再去查看錶,發現你要修改的表不見了。。
step 6 重新再做一遍,這次我們用介面操作顯示如,但表沒有消失:
step 7 修改產生的指令碼,去掉GO,再執行: