数据库语句
SQL Server 2000 應用于開發 范例寶典 --明日科技編著 筆記
1、數據庫空間的增加與收縮
增加可以再屬性中設置,收縮百分比,如0%為收縮后把沒有用到的空間釋放掉。按百分比增長為為加入數據之后按當前內存的多少來增加數據庫的大小。(貌似是這樣的)
2、標識列
(1)、列的數據類型為不帶小數的數值類型
(2)、在進行插入(Insert)操作時,該列的值是由系統按一定規律生成,不允許空值
(3)、列值不重復,具有標識表中每一行的作用,每個表只能有一個標識列。
由于以上特點,使得標識列在數據庫的設計中得到廣泛的使用。
2.1 標識列的組成
創建一個標識列,通常要指定三個內容:
(1)、類型(type)
在SQL Server 2000中,標識列類型必須是數值類型,如下:
decimal、int、numeric、smallint、bigint 、tinyint
其中要注意的是,當選擇decimal和numeric時,小數位數必須為零
另外還要注意每種數據類型所有表示的數值范圍
(2)、種子(seed)
是指派給表中第一行的值,默認為1
(3)、遞增量(increment)
相鄰兩個標識值之間的增量,默認為1。
總結:標識列 一般作為序號列 自動實現遞增。
3、對列進行操作
ALTER table 密碼錯誤 add 個數 int NULL ALTER table 密碼錯誤 drop column 時間? ALTER table 密碼錯誤 alter column 時間 int添加自增列,可以設置初始值,以及自增量
ALTER table 密碼錯誤 add nob int identity(1,1) not null 4、設置公式如設置總金額列=金額*個數,則在設計表界面中,選中總金額->公式 ? 金額*個數自動計算 非常好
手機號 ? 金額 ? 個數 總金額
15013280595 ? ?230 ??2460
5、小數位數
MySQL允許使用非標準語法:FLOAT(M,D)或REAL(M,D)或DOUBLE PRECISION(M,D)。這里,“(M,D)”表示該值一共顯示M位整數,其中D位位于小數點后面。例如,定義為FLOAT(7,4)的一個列可以顯示為-999.9999。MySQL保存值時進行四舍五入,因此如果在FLOAT(7,4)列內插入999.00009,近似結果是999.0001。
6、獲取當前時間
select getdate()7、類型轉換 CAST(ListPrice AS int) CONVERT(int, ListPrice) 都是將ListPrice 這一列轉化為int 類型8、索引
8.1 如果要經常查詢一列,而且這一列是唯一的話可以建立唯一索引,同樣可以對多個列建立唯一索引。 這樣可以提高查詢的效率。 但是其缺點是增加需要磁盤空間,降低添加、刪除、以及更新行的速度。另外還有(聚集索引??)
建立索引前:
select 手機號 from 原始賬號
結果是:
CPU 時間 = 62 毫秒,耗費時間 = 355 毫秒。
建立索引后:
CPU 時間 = 47 毫秒,耗費時間 = 333 毫秒。
8.2 主鍵索引
數據庫表中通常有一列或列的組合,其值用來唯一標識表中的每一行,該列或列的組合稱為表的主鍵,在視圖操作中定義主鍵將自動設置為主鍵索引。能加快查詢速度。
9、查看語句執行時間以及cpu運行情況,可以看語句的執行效率如何
SET STATISTICS PROFILE ON SET STATISTICS IO ON SET STATISTICS TIME ON select * from 原始賬號 SET STATISTICS PROFILE OFF SET STATISTICS IO OFF SET STATISTICS TIME OFF顯示結果如下:SQL Server 執行時間:?
? ?CPU 時間 = 0 毫秒,耗費時間 = 0 毫秒。
SQL Server 分析和編譯時間:?
? ?CPU 時間 = 0 毫秒,耗費時間 = 0 毫秒。
(所影響的行數為 292481 行)
表 '原始賬號'。掃描計數 1,邏輯讀 3362 次,物理讀 0 次,預讀 0 次。
SQL Server 執行時間:?
? ?CPU 時間 = 156 毫秒,耗費時間 = 1463 毫秒。
10、關系的建立與維護
關系的建立可以是一對一,也就是表A和表B的主鍵記錄是唯一的,一一對應。也可以是一對多,表A中的一行,在B中有多行記錄,但是B的都在A中。
其作用是:
防止在從表中添加主表中沒有的ID等,必須主表先加,從表才能加,從表刪除,主表才能刪除。這樣做到了一個關系??梢员Wo關心的數據,放在兩外一個表中。
11、check 約束
這個可以通過check函數來實現,比如說唯一等。
12、sql的注釋方式有兩種:
-- ?和/* */
13、數據庫操作
drop database name--刪除數據庫
sp_detach_db @dbname='ZK'--分離數據庫 sp_attach_db @dbname=ZK,@filename1='F:\\ZKSQL_data.MDF',--附加數據庫@filename2='...._Log.Ldf'其中,分離操作的作用是能夠將數據庫從服務器移除,不能再使用,但是其數據還存在本地磁盤中,通過附加數據庫可以再次使用,然而drop是無法再使用。同樣可以附加單文件數據庫,其日志文件將自動添加。
備份與還原,這里就還是用管理器來操作好了。
14、表的一些操作
create table test( ID int not null, name varchar(50) null ) drop table test --刪除表 alter table 密碼錯誤 add 個數 int NULL --添加列,只有這個不要加column alter table 密碼錯誤 drop column 時間 刪除列 alter table 密碼錯誤 alter column 時間 int 更改列 exec sp_rename 'test','testnew'--更改表名 exec sp_rename 'testnew.name','名稱'--更改列名15、select 語句避免使用not 會讓查詢變慢
--使用別名 select 密碼錯誤.金額 as 金額統計 from 密碼錯誤 select (金額+1) as 金額 from 密碼錯誤 --在查詢結果中添加列,進行多列數據的計算 select sum(金額) as 金額 from 密碼錯誤-- 利用聚合函數 ,同樣需要重命名,且需要用group by 進行分組 --模糊匹配 非常強大,正是我需要的,跟LINUX shell 腳本非常像 --select * from 密碼錯誤 where LEFT(手機號,3) like '158' --158開頭的手機號 非常好用,這里用的是字符函數,同樣可以用數字函數,日期時間函數 --select * from 密碼錯誤 where LEFT(手機號,3) like '15_' --前3為以15開頭的,這里_是匹配一個字符 --select * from 密碼錯誤 where 手機號 like '158%' --%匹配任意多個字符,可以用兩個%進行查詢,但是建議不要用兩個 --select * from 密碼錯誤 where LEFT(手機號,3) like '1[4-5]_'--范圍匹配 --select * from 密碼錯誤 where LEFT(手機號,3) like '1[^4-5]_' --and(...or ...)--這種條件值得注意 格式化字段和結果集利用這個可以解決在號碼中加-的問題,不用每次都去excel中取做,但是由于sql2000不支持mid ,且號碼中含有空格,所以這里用 select LEFT(手機號,3)+ '_'+RIGHT( LEFT(手機號,7),4)+'_'+ RIGHT( LEFT(手機號,11),4) as 手機號 from 密碼錯誤實現了功能,效果如下:134_1814_7589
134_1814_9634
16、字符串函數
LTRIM ?以及 RTRIM ?
ROUND(748.58,-1) ? 當后面數字為負數為 判斷小數點前的位數 ?為0位判斷小數點后一位 ?為正數為判斷后位數
CAST(.. ?AS ?int )
select cast(round(sale/price,0) as int) as 價格in ?not in
17 ?一些select 語句
use HB select * from 總中獎 All 為大于所有的,是里面的最大值,any 為最小的,這里不再贅述 select * from 總中獎 where 金額 > all(select 金額 from 總中獎 where 手機號 in('15013376654','13433921643')) select * from 總中獎 where not (個數 between 2 and 4) --選取個數小于2的 --distinct --distinct 為不選取重復行,若在sum avg max 等聚合函數中用distinct 函數 那么則先去掉重復再做計算 select distinct * from 密碼錯誤 --這里如果沒有對服務密碼進行聚合的話 那么group 必須用到該列select 手機號 ,服務密碼,count(手機號) as 手機號個數 from 密碼錯誤 group by 手機號,服務密碼 having count(手機號)=1 order by 手機號--多個語句 非常棒 --count(*)為統計每個分組統計的個數select * from 密碼錯誤 where 手機號 is not null select top 5 percent * from 密碼錯誤 order by 手機號 desc --這里用到了 percent,默認是升序的 select * from 密碼錯誤 where 手機號 between '13418144500' and '13418147590'-- 字符串的區間判斷方式 select * from 密碼錯誤 where month(日期)=8 --這是month 函數的用法select 所屬部門,性別,avg(工資) as 平均工資 from 工資表 group by 所屬部門, 性別 with cube--這個能夠按部門求出平均工資之后,還能按照部門里面的性別,加出兩個分組 select 所屬部門,性別,avg(工資) as 平均工資 from 工資表 group by 所屬部門,性別 with rollup--好像效果和上面的差不多 select * from 密碼錯誤 compute sum(金額)--這里還是比較方便的 select 金額,count(金額)as 個數 ,sum(金額) as 總金額 from 總中獎 group by 金額 order by 總金額 desc--利用這一句來看所有的分部情況,非常方便 select 編號,銷價 as 銷價最少 ,利潤 as 利潤最少 from table1 where 銷價 in(select min(銷價) from table1)or 利潤 in( select min(利潤) from table1) select 手機號, 金額 from 密碼錯誤 where 金額 in (select min(金額) from 密碼錯誤)-- 不能用 where 金額=min(金額) --一些數學函數 --rand, sin,cos,tan, abs ,sqrt,log,exp,floor為返回不大于所給數的最大整數,ceiling為不小于所給數的最小整數 --日期函數 select dateadd(day,1,getdate()) as tomorrow --返回第二天 select dateadd(year,1,getdate()) as nextyear--返回第二年 select datediff(day,'03/14/2014',getdate()) as daycount--相差天數,其它類似 select day(getdate()) as daynow --返回這個月的第幾天,month,year 類似 select datepart(day,getdate()) as daynow--效果和上面的是一樣的 select 手機號, +char(64)+ cast( 金額 as varchar(20) ) as 金額 from 密碼錯誤 --輸出15013280595 @230 --下面寫一段書上的例子declare @pos int,@s varchar(50) set @pos=1 set @s='i want it' while @pos<datalength(@s) beginselect substring(@s,@pos,1)set @pos=@pos+1 end--上面的例子告訴了我 可以用substring 來取代left rightreplicate 函數,為重復多少遍 如 replicate (手機號,1)為重復一遍 upper()轉化為大寫 space(1)一個空格 substring left(@s,3)等--多表查詢和使用表的別名這個已經會了,就不再贅述 --union--select 手機號 ,金額 from 總中獎 union select 手機號,金額 from 密碼錯誤 order by 金額 desc --select 金額 ,sum(金額) as 總金額,count(金額) as 個數 from 總中獎 group by 金額 union select 金額 ,sum(金額) as 總金額 ,count(金額) as 個數 from 密碼錯誤 group by 金額 order by 金額 desc--注意,可以合并兩個類似的表,但是單一的select 字句不能有order 或者 compute 字句,只能在最后加上 --另外union 會自動刪除重復的行,但是如果加上 union 會保留重復的行 --使用多個嵌套union 這里會按照union 的嵌套順序以及是否使用all 來進行去掉重復操作--in,exists --這個也已經用過了,這里比較其區別 --select * from 原始賬號 where 手機號 in(select 手機號 from 密碼錯誤) --select * from 原始賬號 where 手機號 =any(select 手機號 from 密碼錯誤) --select * from 原始賬號 where exists(select * from 密碼錯誤 where 手機號=原始賬號.手機號)--上面三條語句的功能是一樣的,但是exists只需要判斷后面查詢有結果就可以了,而=any,some 和in 的作用是一樣的 --同樣可以用notin 等 --aome,any, all --all 必須是所有的,some 和any 是一樣的--在select 子句中的子查詢,這個就是不斷的嵌套用as from 等來做,或者聚集函數 特別要注意 這個as 是可以去掉的--delete ... update ...set ..=..--內連接查詢 --這個是可以用a. b.什么來實現的, select a.手機號,a.個數,b.金額 from 總中獎 as a inner join 密碼錯誤 as b on a.手機號=b.手機號 select a.手機號,a.個數,b.金額 from 總中獎 as a ,密碼錯誤 as b where a.手機號=b.手機號 select * from ...顯示兩個表的所有列 --上面兩句的效果是一樣的--自身連接 --自身連接其實也是有作用的,兩個結果都來自同一個表 select a.手機號,a.金額 ,b.金額, (a.金額-b.金額) as 差額 from 密碼錯誤 a inner join 密碼錯誤 b on a.金額>b.金額 order by 差額 desc--外連接 --內連接 只連接匹配的行 --左外連接 包含左邊表的全部行(不管右邊的表中是否存在與它們匹配的行),以及右邊表中全部匹配的行 --右外連接 包含右邊表的全部行(不管左邊的表中是否存在與它們匹配的行),以及左邊表中全部匹配的行 --全外連接 包含左、右兩個表的全部行,不管另外一邊的表中是否存在與它們匹配的行。 --(H)(theta)連接 使用等值以外的條件來匹配左、右兩個表中的行 --交叉連接 生成笛卡爾積-它不使用任何匹配或者選取條件,而是直接將一個數據源中的每個行與另一個數據源的每個行都一一匹配 --上面是看到的關于這幾種連接的區別 --同時可以利用內連接、外鏈接進行多個一起使用,三表一起進行組合 select a.員工編號,b.基本工資,c.請假天數 from (a left inner join b on a.員工編號=b.員工編號) left inner join c on b.員工姓名=c.員工姓名 --感覺還是很好用的樣子--case ,查詢數據select *,狀態= case when 金額<50 then '太少'when 金額>=50 then '滿足要求'end from 密碼錯誤--case ,更新列update 密碼錯誤 set 狀態 = case when 金額<50 then 0when 金額>=50 then 1endalter table 密碼錯誤 drop column 狀態 select * from 密碼錯誤--交叉查詢 --靜態交叉表 --靜態交叉表可以通過select 語句來實現,加上case 等就可以了 --select 員工姓名, sum( case 所在部門 when '食品部' then 銷售業績 else null end) as 食品部業績,sum(...) from 銷售 group by 員工姓名 --上面這個例子,可以以員工為基礎,若在一個部門下有業績,則寫出,否則為null--動態交叉 --動態交叉表就是列表可以根據表中數據的情況動態創建列,不能用select 來實現,但是可以用存儲過程來實現--以后遇到再深入吧以上這些語句,解決了所有sql 中的查詢問題,也終于明白了內連接與外鏈接 以及union的用法,知識對于交叉連接的動態交叉連接,以后有時間再看吧
18、一些更新操作
use HB select * from 密碼錯誤 insert into 密碼錯誤 (手機號,服務密碼,登錄密碼,支付密碼,金額) values(15,33,33,33,1) insert 密碼錯誤 select '1','2','3','4',1 union all select '1','2','3','4',2--這一段和上面的區別是適合于批量插入,這個技能太強大了 update 密碼錯誤 set 手機號='16' where 手機號='15' delete from 密碼錯誤 where 手機號='16'--go 的用法 --當語句過長時,或者當一些語句作為批處理,那么就用go來分開,是批處理的標志go begin tran Update_dataupdate 密碼錯誤 set 手機號='2' where 手機號='1' commit tran Update_data
20、索引
http://www.cnblogs.com/ericwen/archive/2008/09/04/1283998.html
以上是全文索引的鏈接,沒事的時候可以看一下 ,現在還不太懂
21、視圖
創建視圖的作用是可以用來保存臨時表的數據,這樣就不需要導入導出多次,解決了我以前不斷導入導出保存數據的問題,真的是非常好。
GO create view r1 as select * from 總中獎 where exists(select * from 密碼錯誤 where 手機號 = 總中獎.手機號) go exec sp_helptext 'r1' GO select * from r1 GO--修改視圖 go alter view r1 as select * from 密碼錯誤 where 金額>50 go--select * from r1 --對視圖文本進行加密 go create view r2 with encryption as select * from 密碼錯誤 where 金額<=50 go 這樣的話 在企業管理器視圖一覽是看不到r2的select * from r2--刪除視圖 drop view r2--操作視圖 insert into r1(手機號,金額,個數) values('1',20,10) 這里插入失敗 delete r1 where 個數=1 update r1 set 個數=3 where 金額>0 select * from r122、存儲過程
存儲過程最多可以有2100個承諾書,參數名稱必須符合標識符的規則,每個過程的參數僅用于該過程本身,對于可以是cursor數據類型的輸出參數,沒有最大數目的限制。
use HB<pre name="code" class="sql">--創建存儲過程go--這里需要用到動態sql 語句create procedure p1 @表 varchar(20),@ot varchar(20) outputasbegin--declare @sql varchar(50)--set @sql='select * from 密碼錯誤'--exec (@sql) --這兩種方法都是可以的,下面這種加上了n,但是這里由于這里用到外面的表 ,所以要用動態語句,只能用下面的declare @sql nvarchar(100)set @sql=N'select * from '+@表exec sp_executesql @sqlset @ot='存在表'+@表--print @otreturn 1endgo--修改存儲過程--查看存儲過程exec sp_helptext p1 --查看相關定義的代碼exec sp_help p1 --查看創建時間等信息--重命名存儲過程exec sp_rename p1,pexec sp_helptext p--刪除存儲過程drop procedure p--執行存儲過程godeclare @ret int,@ot varchar(20)exec @ret=p1 '密碼錯誤',@ot output --切記這里要加上outputprint @retprint @otgo--擴展存儲過程sp_addextendedproc 'xp_hello', 'c:\Program Files\Microsoft SQL Server\MSSQL12.0.MSSQLSERVER\MSSQL\Binn\xp_hello.dll';--這里xp-hello 為擴展存儲過程的函數名,后面的為路徑--對存儲過程的定義文本進行加密--和視圖一樣 加上 with encryption 即可--應用存儲過程sp_monitor 和sp_spaceused--具體怎么用還不是很清楚--自動執行存儲過程exec sp_procoption 'p1','startup','on' 23、觸發器觸發器是一種特殊類型的存儲過程,與表格緊密相連,當用戶修改表中數據時,觸發器將自動執行。觸發器可以使用語句進行復雜的邏輯處理,它基于一個表創建,但是可以對多個表進行操作。常常用于復雜的業務規則。
注意:
其他的一樣,create trigger 語句必須是批處理的第一個語句。
這里用到別人的語句
SQL Server 觸發器
觸發器是一種特殊類型的存儲過程,它不同于之前的我們介紹的存儲過程。觸發器主要是通過事件進行觸發被自動調用執行的。而存儲過程可以通過存儲過程的名稱被調用。
? 什么是觸發器
??? 觸發器對表進行插入、更新、刪除的時候會自動執行的特殊存儲過程。觸發器一般用在check約束更加復雜的約束上面。觸發器和普通的存儲過程的區別是:觸發器是當對某一個表進行操作。諸如:update、insert、delete這些操作的時候,系統會自動調用執行該表上對應的觸發器。SQL Server 2005中觸發器可以分為兩類:DML觸發器和DDL觸發器,其中DDL觸發器它們會影響多種數據定義語言語句而激發,這些語句有create、alter、drop語句。
?
??? DML觸發器分為:
??? 1、 after觸發器(之后觸發)
??????? a、 insert觸發器
??????? b、 update觸發器
??????? c、 delete觸發器
?
??? 2、 instead of 觸發器 (之前觸發)
?
??? 其中after觸發器要求只有執行某一操作insert、update、delete之后觸發器才被觸發,且只能定義在表上。而instead of觸發器表示并不執行其定義的操作(insert、update、delete)而僅是執行觸發器本身。既可以在表上定義instead of觸發器,也可以在視圖上定義。
?
??? 觸發器有兩個特殊的表:插入表(instered表)和刪除表(deleted表)。這兩張是邏輯表也是虛表。有系統在內存中創建者兩張表,不會存儲在數據庫中。而且兩張表的都是只讀的,只能讀取數據而不能修改數據。這兩張表的結果總是與被改觸發器應用的表的結構相同。當觸發器完成工作后,這兩張表就會被刪除。Inserted表的數據是插入或是修改后的數據,而deleted表的數據是更新前的或是刪除的數據。
?
| 對表的操作 | Inserted邏輯表 | Deleted邏輯表 |
| 增加記錄(insert) | 存放增加的記錄 | 無 |
| 刪除記錄(delete) | 無 | 存放被刪除的記錄 |
| 修改記錄(update) | 存放更新后的記錄 | 存放更新前的記錄 |
??? Update數據的時候就是先刪除表記錄,然后增加一條記錄。這樣在inserted和deleted表就都有update后的數據記錄了。注意的是:觸發器本身就是一個事務,所以在觸發器里面可以對修改數據進行一些特殊的檢查。如果不滿足可以利用事務回滾,撤銷操作。
?
? 創建觸發器
??? 語法
create trigger tgr_name on table_name with encrypion –加密觸發器for update... asTransact-SQL??? # 創建insert類型觸發器
--創建insert插入類型觸發器 if (object_id('tgr_classes_insert', 'tr') is not null)drop trigger tgr_classes_insert go create trigger tgr_classes_insert on classesfor insert --插入觸發 as--定義變量declare @id int, @name varchar(20), @temp int;--在inserted表中查詢已經插入記錄信息select @id = id, @name = name from inserted;set @name = @name + convert(varchar, @id);set @temp = @id / 2; insert into student values(@name, 18 + @id, @temp, @id);print '添加學生成功!'; go --插入數據 insert into classes values('5班', getDate()); --查詢數據 select * from classes; select * from student order by id;???? insert觸發器,會在inserted表中添加一條剛插入的記錄。
?
??? # 創建delete類型觸發器
--delete刪除類型觸發器 if (object_id('tgr_classes_delete', 'TR') is not null)drop trigger tgr_classes_delete go create trigger tgr_classes_delete on classesfor delete --刪除觸發 asprint '備份數據中……'; if (object_id('classesBackup', 'U') is not null)--存在classesBackup,直接插入數據insert into classesBackup select name, createDate from deleted;else--不存在classesBackup創建再插入select * into classesBackup from deleted;print '備份數據成功!'; go -- --不顯示影響行數 --set nocount on; delete classes where name = '5班'; --查詢數據 select * from classes; select * from classesBackup;?? delete觸發器會在刪除數據的時候,將剛才刪除的數據保存在deleted表中。
?
??? # 創建update類型觸發器
--update更新類型觸發器 if (object_id('tgr_classes_update', 'TR') is not null)drop trigger tgr_classes_update go create trigger tgr_classes_update on classesfor update asdeclare @oldName varchar(20), @newName varchar(20);--更新前的數據select @oldName = name from deleted;if (exists (select * from student where name like '%'+ @oldName + '%'))begin--更新后的數據select @newName = name from inserted;update student set name = replace(name, @oldName, @newName) where name like '%'+ @oldName + '%';print '級聯修改數據成功!';endelseprint '無需修改student表!'; go --查詢數據 select * from student order by id; select * from classes; update classes set name = '五班' where name = '5班';???? update觸發器會在更新數據后,將更新前的數據保存在deleted表中,更新后的數據保存在inserted表中。
?
??? # update更新列級觸發器
if (object_id('tgr_classes_update_column', 'TR') is not null)drop trigger tgr_classes_update_column go create trigger tgr_classes_update_column on classesfor update as--列級觸發器:是否更新了班級創建時間if (update(createDate))beginraisError('系統提示:班級創建時間不能修改!', 16, 11);rollback tran;end go --測試 select * from student order by id; select * from classes; update classes set createDate = getDate() where id = 3; update classes set name = '四班' where id = 7;???? 更新列級觸發器可以用update是否判斷更新列記錄;
?
??? # instead of類型觸發器
?????? instead of觸發器表示并不執行其定義的操作(insert、update、delete)而僅是執行觸發器本身的內容。
?????? 創建語法
create trigger tgr_name on table_name with encryptioninstead of update... asT-SQL???
????? # 創建instead of觸發器
if (object_id('tgr_classes_inteadOf', 'TR') is not null)drop trigger tgr_classes_inteadOf go create trigger tgr_classes_inteadOf on classesinstead of delete/*, update, insert*/ asdeclare @id int, @name varchar(20);--查詢被刪除的信息,病賦值select @id = id, @name = name from deleted;print 'id: ' + convert(varchar, @id) + ', name: ' + @name;--先刪除student的信息delete student where cid = @id;--再刪除classes的信息delete classes where id = @id;print '刪除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的信息成功!'; go --test select * from student order by id; select * from classes; delete classes where id = 7;???
????? # 顯示自定義消息raiserror
if (object_id('tgr_message', 'TR') is not null)drop trigger tgr_message go create trigger tgr_message on studentafter insert, update as raisError('tgr_message觸發器被觸發', 16, 10); go --test insert into student values('lily', 22, 1, 7); update student set sex = 0 where name = 'lucy'; select * from student order by id;??? # 修改觸發器
alter trigger tgr_message on student after delete as raisError('tgr_message觸發器被觸發', 16, 10); go --test delete from student where name = 'lucy';??? # 啟用、禁用觸發器
--禁用觸發器 disable trigger tgr_message on student; --啟用觸發器 enable trigger tgr_message on student;??? # 查詢創建的觸發器信息
--查詢已存在的觸發器 select * from sys.triggers; select * from sys.objects where type = 'TR';--查看觸發器觸發事件 select te.* from sys.trigger_events te join sys.triggers t on t.object_id = te.object_id where t.parent_class = 0 and t.name = 'tgr_valid_data';--查看創建觸發器語句 exec sp_helptext 'tgr_message';??? # 示例,驗證插入數據
if ((object_id('tgr_valid_data', 'TR') is not null))drop trigger tgr_valid_data go create trigger tgr_valid_data on student after insert asdeclare @age int,@name varchar(20);select @name = s.name, @age = s.age from inserted s;if (@age < 18)beginraisError('插入新數據的age有問題', 16, 1);rollback tran;end go --test insert into student values('forest', 2, 0, 7); insert into student values('forest', 22, 0, 7); select * from student order by id;??? # 示例,操作日志
if (object_id('log', 'U') is not null)drop table log go create table log(id int identity(1, 1) primary key,action varchar(20),createDate datetime default getDate() ) go if (exists (select * from sys.objects where name = 'tgr_student_log'))drop trigger tgr_student_log go create trigger tgr_student_log on student after insert, update, delete asif ((exists (select 1 from inserted)) and (exists (select 1 from deleted)))begininsert into log(action) values('updated');endelse if (exists (select 1 from inserted) and not exists (select 1 from deleted))begininsert into log(action) values('inserted');endelse if (not exists (select 1 from inserted) and exists (select 1 from deleted))begininsert into log(action) values('deleted');end go --test insert into student values('king', 22, 1, 7); update student set sex = 0 where name = 'king'; delete student where name = 'king'; select * from log; select * from student order by id; 24、游標的使用游標提供了一種對從表中檢索出的數據進行操作的靈活手段
其必須有4個組成部分
聲明游標
打開游標
從一個游標中查找信息
關閉游標
use HB--創建游標 GO declare cur cursor for select * from 密碼錯誤 order by 手機號 desc --for read only --創建只讀游標 --for update --更新游標 open cur--打開游標 fetch next from cur while @@fetch_status=0 beginfetch next from cur end close cur--關閉游標 deallocate cur--釋放游標--將查詢到的數據fetch 進變量 GO declare cur cursor for select * from 密碼錯誤 order by 手機號 desc open cur--打開游標 declare @手機號 varchar(20),@服務密碼 varchar(20),@登錄密碼 varchar(20),@支付密碼 varchar(20),@金額 int,@個數 int,@總金額 int fetch next from cur into @手機號,@服務密碼,@登錄密碼,@支付密碼,@金額,@個數,@總金額 while @@fetch_status=0 beginprint @手機號fetch next from cur into @手機號,@服務密碼,@登錄密碼,@支付密碼,@金額,@個數,@總金額end close cur--關閉游標 deallocate cur--釋放游標--設計帶滾動的數據查詢 GO declare cur scroll cursor for select * from 密碼錯誤 order by 手機號 desc open cur--打開游標 fetch next from cur fetch prior from cur --前一行 fetch first from cur fetch last from cur--最后一行 fetch absolute 2 from cur-- 絕對排序的第二行 fetch relative 2 from cur --從當前游標數下面第2行,同樣有-2之類的 close cur--關閉游標 deallocate cur--釋放游標--使用游標更新數據 --利用 where current of cur 來操作當前行 GO declare cur scroll cursor for select * from 密碼錯誤 order by 手機號 desc for update of 個數 --只允許更新個數 open cur--打開游標 fetch next from cur update 密碼錯誤 set 個數=3 where current of cur --同樣可以用 delete fetch first from cur close cur--關閉游標 deallocate cur--釋放游標--利用索引改變游標中行的順序,利用索引先排好序,再操作 --建立索引 create index index1 on 密碼錯誤(手機號 desc) GO declare cur scroll cursor for select * from 密碼錯誤 with (index(index1))--那么里面就不能再用排序了 open cur--打開游標 fetch next from cur close cur--關閉游標 deallocate cur--釋放游標25、分布式查詢
分布式查詢可以訪問來自多種異類數據源的數據,而這些數據可存儲在相同或不同的計算機上。鏈接服務器要做的工作是:配置好連接服務器的名字、相應的位置和登錄信息,以便SQL SERVER 可以存取鏈接服務器上的數據。
use HB /* --建立鏈接服務器 exec sp_addlinkedserver @server='hblk',--注意, @srvproduct='SQL Server' */--查看鏈接服務器 --exec sp_linkedservers--刪除鏈接服務器,這里和刪除視圖等不一樣 --exec sp_dropserver 'hblk' --建立映射登錄 /* go sp_addlinkedsrvlogin 'aaa',--遠程服務器名字 'false', 'sa', --本地登錄 'ruser',--遠程登錄用戶名 'rpaw'--密碼 */--查詢映射登錄 --exec sp_helplinkedsrvlogin--刪除映射登錄 --exec sp_droplinkedsrvlogin --'遠程服務器名', --'sa'--設置鏈接選項,這里是設置數據訪問屬性為true,其余的同樣可以通過后兩位來進行設置 /* go exec sp_serveroption 'hblk', 'data access', true */建立好了與外部數據源的鏈接后,SQL Server 就可以在查詢中引用外部數據了。其和本地查詢類似
這個功能,我以前建立鏈接服務器,用作業來操作數據的時候,是有用過的。
use HB--簡單查詢 --select * from [服務器名].[數據庫名].[所有者名].[表名]--利用OpenDatasource()查詢 --利用它來代替服務器名,當然還有其它用途,這個還不知道--用OpenQuery查詢 --select * from openquery(hblk,'select * from [數據庫名].[所有者名].[表名]')--OpenRowSet() --select * from openrowset('sqloledb','hblk';'sa''....)不確定怎么用--分布式事務處理 set xact_Abort on begin distributed transaction --開始事務 update 密碼錯誤 set 金額=10 update [服務器名].[數據庫名].[所有者名].[表名] set ... commit transaction --提交事務
總結
- 上一篇: SpringBoot + SpringS
- 下一篇: 【mysql】只使用数据库DB如何实现-