如果新建的表中某一列屬性有約束,那麼在sqlserver中導入數據過程中,如果有不符合該約束的值,就會導致衝突,導入失敗。
一般的做法是先導入一個沒有約束的表,然後在sqlserver中通過查詢語句篩選掉不符合約束條件的元組,然後insert進入有約束的表。
顯然這種方式簡單但是會損耗空間,並且如果導入的數據表如果很多,這樣的操作會很繁瑣。
下面介紹用觸發器解決這一問題的方式:
先建表
create table student(
number nchar(8) not null,
name varchar(50) not null,
sex nchar(2) not null check(sex in ('男','女')),
age int not null,
class int not null,
score decimal(5,2) check(score>=0 and score <=10),
time varchar(50)
)
這裏爲score屬性添加了約束
創建觸發器
sqlserver的觸發器沒有before語法,所以只能通過重寫insert來解決,如果數據庫是mysql可以用before,會方便很多
Create Trigger scorecheck
ON student
Instead Of Insert //創建觸發器的基本語句
AS
Begin
Set Nocount On; //這裏開始建立虛表
Declare @number nchar(8),
@name varchar(50),
@sex nchar(2),
@age int,
@class int,
@score decimal(5,2),
@time varchar(50)
DECLARE YB CURSOR FOR
SELECT [number],[name],[sex],[age],[class],[score],[time] FROM INSERTED //inserted是sqlserver中自帶的參數,表示導入的表
OPEN YB //打開導入的虛表
FETCH NEXT FROM YB INTO @number,@name,@sex,@age,@class,@score,@time
//獲取第一行的元組
WHILE @@FETCH_STATUS = 0 //由於表有很多元組,我們需要遍歷每一行
//這裏相當於while hasnextline
begin
if(@score)<0 or (@score)>10 //篩選
begin
print '分數不合法'
end
else
begin
insert into student(number,name,sex,age,class,score,time) values(@number,@name,@sex,@age,@class,@score,@time)
//符合條件的元組插入表中
end
FETCH NEXT FROM YB INTO @number,@name,@sex,@age,@class,@score,@time
//獲取下一行
END
CLOSE YB
DEALLOCATE YB
End
導入數據
sqlserver自帶的導入數據程序是不經過我們創建的觸發器的,就是我們不能通過 任務->導入文件 來導入數據
我們只能手寫導入文件
通過bulk insert導入文件,這邊文件類型是csv,所以分隔符是,和\n,不同的文件類型有不同的分隔符。
此外,一般數據庫都設有權限,你可能沒有權限導入放在桌面或其他文件夾的文件,解決方法是把該文件放在C盤
bulk insert student
from 'C:\student.csv' //C盤的csv文件
with(
FIELDTERMINATOR=',',
ROWTERMINATOR='\n' ,
FIRSTROW=2,
FIRE_TRIGGERS //這行的意思是導入過程經過所有觸發器
)
到這裏就可以了,不合法的數據會被篩選掉不導入,並且有數據不合法的提示。