轉貼 MSSQL基礎知識

SQL-Structured Query Language

--(開啓SQL服務:net start mssqlserver)

--(在命令行中輸入'sqlwb'命令可打開SQL管理器 )

--(如果要執行多條命令中的一條,鼠標選定後再按F5執行)

create database sales                           --創建一個名爲sales的數據庫
on
(
name='sales_data',
filename='d:/sales_data.mdf',
size=10,
maxsize=50,
filegrowth=5
)
log on
(
name='sales_log',
filename='d:/sales_log.ldf',
size=10,
maxsize=50,
filegrowth=5
)

drop database sales                             --刪除所創建的數據庫

sp_helpdb sales                                 --查看數據庫的相關信息

sp_helpfile                                     --查看當前數據庫數據文件與日誌文件的相關信息


sp_detach_db sales                              --轉移數據庫時分離數據庫

sp_attach_db sales,@filename1='數據文件路徑名'  --整合分離的數據庫                 
                  ,@filename2='日誌文件路徑名'

--(如何減小數據庫日誌文件的大小:  a.分離數據庫 b.轉移日誌文件 c .整合數據庫但不指定日誌文件)

--數據庫的備份

sp_addumpdevice 'disk','mydisk','d:/sales.bak'  --添加設備。disk表示目標設備類型,mydisk表示目標設備邏輯名稱,d:/sales.bak表示目標設備物理名稱

backup database sales to mydisk                 --向設備寫入數據.其中的sales指數據庫名,mydisk爲自定的設備標示符

restore database sales from mydisk              --恢復數據庫

sp_dropdevice mydisk                            --刪除設備

EXEC sp_dboption 'sales','read only','true'     --設數據庫爲只讀

EXEC sp_dboption 'sales',autoshrink,true        --設數據庫爲自動壓縮

EXEC sp_dboption 'sales','single user'          --設數據庫爲單用戶

--(以上命令中單引號可加可不加,但名字中出現空格的一定要加.大小寫不分)

DBCC shrinkdatabase (sales,10)                  --將數據庫中的文件減小,使數據庫中有10%的可用空間

---------------------------------------------------------------------------------------------------------------

create table goods                              --建表的第一種約束語法
(
gid int primary key,
gname varchar(10) unique,
price money check(price>300),
ldate datetime default getdate()
)

insert into goods(gid,gname,price) values(105,'computer5',1222)--當表中有默認值約束時向表中輸入數據

insert into goods values(107,'computer',13434,default)         --當表中有默認值約束時向表中添加數據的另一種方法

sp_help goods                                   -- 用來查詢表的信息

select *from goods    --用來查詢表中的內容

create table goods                              --建表的第二種約束語法
(
gid int constraint pg_id primary key,           --用constraint 給表中的列約束起名
gname varchar(10) constraint uq_name unique,
price money constraint ck_price check(price>300),
ldate datetime constraint df_date default getdate()
)

alter table goods drop 約束名                   --用來刪除約束

 create table goods                             --建表的第三種約束語法
(
gid int not null,
gname varchar(10),
price money,
ldate datetime
)

alter table goods add constraint pk_id primary key(gid)
alter table goods add constraint uq_name unique(gname)
alter table goods add constraint cj_price check(price>300 and price<1000)
alter table goods add constraint df_ldate default getdate() for ldate

create table gp                                 --創建引用goods的表gp
(
wno int identity(1001,1) primary key,           --identity爲設定自動增長列標示,1001是起始數字,references爲引用
      --在插入數據時不能給自動增長列賦值,插入字符型數據與日期型數據時要用單引號
gno int constraint fk_id foreign key            --定義gno爲表的外鍵
references goods(gid) 
)
drop table gp
create table gp
(
wno int identity(1001,1) primary key,
gno int
)

alter table gp add constraint fk_id foreign key(gno) references goods(gid)--效果同上,另一種寫法

alter table 表名 add 列名 數據類型               --爲表加上一列

alter table 表名 drop column 列名                --刪除一列

delete from 表名 where 條件(如:gid=1001)        --刪除符合where條件的一行

insert into 表名 values (default)                --爲表附默認值

insert into 表名(列名) values()                  --同上

--默認值約束不影響歷史數據!

--當爲包含有自動增長列的表添加數據時不須爲自動增長列附值

delete from 表名                                 --全刪表中數據

delete from 表名 where gid=1001                  --刪除符合條件(gid=1001)的數據

truncate table 表名                              --截斷表,不可帶條件,不能截斷被外鍵引用的表,不管該表中是否有數據

update 表名 set 列名=列值                        --用來更新數據

where gid=1000 or gid=1001

update 表名 set 列名=列值                        --同上

where gid in(1000,1001)

update 表名 set 列名1=列值1,列名2=列值2,......  --爲多列更新值

where 條件

--事務可分爲3種:1。顯式事務 2。隱式事務 3。自動提交事務(系統默認爲自動提交事務)    


select * from 表名                               --查詢表中數據

begin tran t1            --開始一個顯式事務 

update 表名 set 列名=列值                        --更新數據

where not 條件                                   --更新條件

rollback t1                                     --回滾一個事務    

commit t1                                       --提交事務(以後不能再回滾了)

--隱式事務通過 SET IMPLICIT_TRANSACTIONS ON語句將隱式事務設爲開,當連接以隱式事務操作時,
--將在提交或回滾後自動啓動新事務,無須描述事務的開始,只須提交或回滾事務

SET IMPLICIT_TRANSACTIONS ON


select * into 新表名 from 舊錶名                 --備份現有表數據到新表中,它能複製表的結構,數據。
--還可以加上條件過濾如果只想複製到指定列,用列名代替*即可

--如果只想複製表的結構而不想複製數據,加上永不成立條件。(如where 1>3) 

--該語句自動創建新表,但原表的約束關係不能被複制,但not null與identity屬性可複製

select 列名1,列名2,列名3,......
into 新表名 from 舊錶名    --備份現有表中的部分數據到新表中

alter table gp add constraint gp_id foreign key(gno) references
goods(gid) on delete cascade on update no action --這是用來進行級連更新和刪除的語法,
      --在on的後面可加上: 1.delete cascade 2.delete no action 3.update cascade 4.update no action

--------------------------------------------------------------------------------------------------------------------------------------------------

create table gp
(
pid int identity(100,1) primary key,
pname varchar(10),
ptel varchar(12) check(ptel like '[0-9][0-9][0-9][-][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')
)

                                                --這是電話號碼約束的方法

select host_name()        --查看本機名

select getdate()                                --獲取當前時間

select user                                     --查看當前用戶

xp_cmdshell 'dir'                               --執行DOS命令dir,將DOS命令寫在''中間即可

xp_cmdshell 'net user EKIN 1234 /add'           --添加windows用戶,EKIN爲用戶名,1234爲密碼


xp_cmdshell 'net user EKIN /delete'             --刪除windows用戶


xp_cmdshell 'net user administrator 9527'       --修改管理員密碼

Uniqueidentifier              --這是數據類型的一種,全球唯一的標示符,用newid()函數給這個類型的數據提供值

                           
select *from gp INNER JOIN goods on gp.gno=goods.gid               --內聯接 僅顯示兩個聯接表中的匹配行的聯接
 
select *from gp LEFT OUTER JOIN goods on gp.gno=goods.gid          --左向外聯接  包括第一個命名錶(“左”表,出現在JOIN子句的最左邊)中的所有行。不包括“右”表中的不匹配行   

select *from gp right OUTER JOIN goods on gp.gno=goods.gid         --右向外聯接  包括第二個命名錶(“右”表,出現在JOIN子句的最右邊)中的所有行。不包括“左”表中的不匹配行  

select *from gp full OUTER JOIN goods on go.gno=goods.gid          --完整外部聯接  包括所有聯接表中的所有行,不管它們是否匹配

select *from gp CROSS JOIN goods                                   --交叉聯接  在這類聯接的結果集內,兩個表中每個可能成對的行佔一行,不論它們是否匹配


select *from goods where price between 1300 and 1800               --區間查詢。查價格在1300-1800間的貨物

select *from goods where gid in(1001,1003)                         --查詢貨物ID爲1001和1003的產品,不是查1001與1003之間的貨物!in前加not指除了1001和1003以外的貨物

select *from goods where price not between 1300 and 1500           --查price不在1300與1500之間的貨物

select *from goods where price is null                             --查詢價格爲空的貨物

select *from goods where gname like ' '                            --模糊查詢。''中加 % 代表gname中的任意字符, _ 代表gname中的一個字符,[ ]代表一個區間,[^]代表不在這區間

                   --比如:select *from Renyuan where age like '2[^1-4]'

--在SQL中一個漢字與一個符號或字母都只佔一個字符,  用  nchar  可錄漢字。

select max(price) as 最高價格 from goods                           --as爲取別名,max()爲求最大值的函數,min()求最小值,arg()求平均值


select sum(price) from goods                                       --求price 的總和,sum()用來求總和的

--單行與聚合不能一起使用,除非依據單行進行分組。(比如:select gid, max(price)from goods) 

select gid,  max(price) as 最高價格 from goods group by gid        --按gid進行分組,就是求同類gid貨物的最高價格

--在where子句中不能出現聚合函數(比如:where max(price)>1300)

select gid,max(price) as 最高價格 from goods group by gid having max(price)>1300  --用having指定分組條件,代替where

create table info
(
 ino int,age int
)

insert into info values(12,22)
select *from info order by ino asc,age desc                        --order by指定排序條件,asc表示升序,desc表示降序.

--以上這個程序結果爲編號按照升序排列,在編號相同的情況下,按age降序排列

select max(convert(int,price)) from goods                          --在goods表中查詢出價格最高的貨物,並且強制轉換price的類型  

select top 1 * from goods where price>4000      --在goods表中查詢出價格大於4000的貨物資料,並只顯示第一條記錄

 

SQL-Structured Query Language
       
-----------------------------------------------------------------------------------------------
select user                                     --查詢當前用戶

select host_name()    --查詢服務器的主機名稱

create table dept
(did int primary key,
dname varchar(10))

drop table info
insert into dept    --結果集聯合插入數據
select '1001','市場部'
union select '1002','學術部'
union select '1003','人事部'
union select '1004','公關部'

select * from info

create table job
(jid int primary key,
jname varchar(10))

insert into job    
select '2001','工人'
union select '2002','技術員'
union select '2003','領班'
union select '2004','管理員'

create table emp    --表裏的on update與on delete爲級連更新和級連刪除  
(eid int primary key,    
ename varchar(10),
dno int references dept(did) on delete cascade on update no action,
jno int references job(jid) on delete no action on update cascade)

select * from emp where eid like '[0-8][0-10][0-8][0-12]'--這是模糊查詢,[]裏是指範圍,[0-12]表示
      --可取範圍是0,1,2;[0-3]指可取範圍是0,1,2,3;like前加上not表示不在此範圍內

create table info
(item varchar(10),
color varchar(10),
num int)

insert into info
select 'table','blue',124
union select 'table','red',223
union select 'chair','blue',101
union select 'chair','red',210
union select 'table','blue',226

select item,color,max(num) as allsum from info group by item,color --這條語句中group by子句中如沒有出現color則出錯,
--因爲單行和聚合不能同時出現,除非依據選擇列表中所有的單行進行分組
--當選擇列表中存在單行和聚合時,除聚合外的單行必須出現在group by 後
--上述語句結果集分組依據:當item,color同時相同時才能分在同一個組裏


select item,color,sum(num) as allsum from info group by item,color with CUBE
--cube 相當於一個統計,做交叉表,它在group by子句中指定,該語句的選擇列表應包含維度列以及聚合函數表達式
--維度列是指group by後面依據分組的單行,選擇列表爲select後面的列.


select item,color,sum(num) as allsum from info group by item,color with ROLLUP
--另一種統計方法,其中group by後面第一列爲統計列,不會按照其他的列進行分組統計,這是ROLLUP與CUBE統計的區別


if(EXISTS(select * from info where num=999)) --EXISTS 關鍵字引入一個子查詢時,就相當於進行一次存在測試,

print 'ok'     --在 EXISTS 前加上 NOT 表示不存在的判定


create table goods1
(gid int ,
num int,
price numeric(8,3),
total as num*price)                             --計算列的表示方法。計算列是自動進行計算的,不需要出現在選擇列表中,不用給它賦值


select *from info where num>3
order by item      
COMPUTE sum(num),count(num) by item             --COMPUTE子句生成合計作爲附加的彙總列出現在結果集的最後。
      
--當COMPUTE後不帶 by 子句時,select語句有兩個結果集,第一個結果集是包含選擇列表信息的所有明細行。的二個結果集有一行,其中包含COMPUTE子句中所指定的聚合函數的合計
--當COMPUTE後帶 by 子句時(實際上就是添加計算依據列表),計算依據列表一定要與排序列表相匹配。計算依據列表select條件的 每個組 都有兩個結果集
--每組第一個結果集是明細行集,包含該組選擇列表的信息;每組第二個結果集只有一行,包含該組的COMPUTE子句中所指定的聚合函數的小計


create table station
(sid int primary key,
sname varchar(10))

create table line
(lid int primary key,
lname varchar(10),
in_sid int references station(sid),
out_sid int references station(sid))

alter table line add constraint ck check (in_sid<>out_sid)    --防止In與Out重複而做的約束

insert into station values(1001,'西安')
insert into station values(1002,'太原')
insert into station values(1003,'北京')
insert into station values(1004,'鄭州')

insert into line values(1,'東線',1001,1002)
insert into line values(2,'南線',1002,1001)
insert into line values(3,'西線',1003,1004)
insert into line values(4,'北線',1004,1002)

drop table line
select *from line
select *from station

select line.lid,line.lname,s1.sname as in_sid,s2.sname as out_sid from line,
station s1,station s2 where line.in_sid=s1.sid and line.out_sid=s2.sid
--"station s1"與"station s2"爲給station 表起別名


select sid,CASE sname                            --CASE 語句後要帶上列名,多列的情況列名用逗號隔開,CASE 語句不改變數據庫的物理結構,只改變顯示方法
when '西安' then '長安'
when '鄭州' then '開封'
else '不知道'
END as sname from station


select sid,CASE      --CASE 語句的另一種寫法,結果同上
when sname='西安' then '長安'
when sname='鄭州' then '開封'
else '不知道'
END as sname from station


create table shift
(wno int primary key,
sid int,
ex_num money,
ex_date datetime default getdate()
)
alter table shift add constraint ck_shift check(sid>=1 and sid<=4)

insert into shift values(1001,1,300,default)
insert into shift values(1002,2,100,default)
insert into shift values(1003,3,200,default)
insert into shift values(1004,4,340,default)
insert into shift values(1005,1,210,default)
insert into shift values(1006,2,320,default)

select sum(CASE sid when 1 then ex_num else 0 END) as s1,
sum(CASE sid when 2 then ex_num else 0 END) as s2,
sum(CASE sid when 3 then ex_num else 0 END) as s3,
sum(CASE sid when 4 then ex_num else 0 END) as s4
into newtab from shift     
       --用CASE語句顯示shift表中不同流水號的ex_num的統計
select *from newtab


declare @a int,@b int     --定義變量a,b
set @a=10      --給變量賦值 
set @b=80     
set @a=@a+@b      --進行計算 
print @a      --在屏幕上輸出計算後變量a的值


declare @person table(pid int,    --定義特殊的table型變量 person的方法。table型變量類似於C語言中的結構體。
pname varchar(10),age int)    --但執行時要連同它的定義一起選中執行

insert into @person values(1001,'accp',23)
insert into @person values(1002,'accp1',3)
insert into @person values(1003,'accp2',23)
select *from @person


create table #tab      --在創建表時在表名前加上一個"#"以創建局部臨時表。一旦局部臨時表與服務器脫離連接則不會存在。
(a int primary key,             --它可分爲全局與局部的臨時表,在創建表時在表名前加上兩個"#"則可創建全局臨時表,
b int)               --全局臨時表與所有連接均斷開後則不存在。
--在臨時表中可以使用主鍵約束,但外鍵約束不起作用!在臨時表中創建的Check約束起作用 

 
select object_id('info1')                         --獲取數據庫對象的唯一ID,用object_id('數據庫對象名')函數。
--如果該對象存在則返回代表該對象的唯一標識符,否則返回NULL


select name from syscolumns where id=object_id('info') --查詢數據庫中指定的表有多少字段

select name from sysobjects where xtype='U'       --查詢數據庫中有多少張用戶表


waitfor delay '00:00:03' select *from info        --到指定延遲後執行SQL語句

waitfor time '15:48:30' select *from info         --到指定時間執行SQL語句


USE master       --用While循環計算1到100的和     
declare @sum int,@i int
set @sum=0
set @i=0
while(@i<=100)
BEGIN
set @sum=@sum+@i
select @i=@i+1
END
print @sum
GO        --GO關鍵字標誌着批處理的結束,用批處理可以減輕數據庫服務器的負擔

While(select AVG(price) from goods)<4000   --While循環與if語句嵌套的經典舉例(解決貨物漲價的基本控制語句)
BEGIN
 update goods set price=price*2
 if(select max(price) from goods)>3000
 break
 else
 continue
END

--類型轉換函數有cast()與convert()兩種。

select cast(1234 as varchar(10))                  --把int型數據轉換成varchar類型。目標數據類型與源數據類型必須是SQL所支持的類型

select convert(varchar(10),1234)    --效果同上,用convert進行轉換


create table emp(eid int primary key,
ename varchar(10),pwd varbinary(20))    --varbinary數據類型是用來設置加密數據的類型

insert into emp values(1001,'rose',cast('2004/3/27' as varbinary(20)))

select * from emp

select eid,ename,cast(pwd as varchar(10)) as pwd from emp

--子查詢:當子查詢的結果唯一的時候,可以使用比較運算符,也可以使用集合運算符,
--當查詢結果不唯一時,能且只能使用集合運算符。
--關係運算符有:>,<,<=,>=,=,<>
--集合運算符有:IN,NOT IN

select count(distinct gid)  from goods            --SQL中去除重複記錄用DISTINCT去除


SELECT 語句                                      
UNION [ALL]
SELECT 語句

--多條語句結果集用UNION關鍵字合併,合併後的結果不重複。
--要想不刪除重複記錄,用 ALL 關鍵字
--其中每個SELET語句必須具有相同的結構,列次序,數目,類型要相同。

SELECT empno,ename,sal from emp
 UNION
SELECT empno,ename,sal from emp1

 

--15個全局變量:

select @@connections  --返回自上次啓動 Microsoft? SQL Server? 以來連接或試圖連接的次數。

select @@cpu_busy  --返回自上次啓動 Microsoft? SQL Server? 以來 CPU 的工作時間,單位爲毫秒(基於系統計時器的分辨率)。

select @@cursor_rows  --返回連接上最後打開的遊標中當前存在的合格行的數量。

select @@datefirst  --返回 SET DATEFIRST 參數的當前值,SET DATEFIRST 參數指明所規定的每週第一天:1 對應星期一,2 對應星期二,依次類推,用 7 對應星期日。

select @@error   --返回最後執行的 Transact-SQL 語句的錯誤代碼。

select @@language  --返回當前使用的語言名。

select @@version  --返回 Microsoft? SQL Server? 當前安裝的日期、版本和處理器類型。

select @@max_connections --返回 Microsoft? SQL Server? 上允許的同時用戶連接的最大數。返回的數不必爲當前配置的數值。

select @@trancount  --返回當前連接的活動事務數。

select @@timeticks  --返回一刻度的微秒數。

select @@rowcount  --返回受上一語句影響的行數。

select @@fetch_status  --返回被 FETCH 語句執行的最後遊標的狀態,而不是任何當前被連接打開的遊標的狀態。

select @@servicename  --返回 Microsoft? SQL Server? 正在其下運行的註冊表鍵名。
    --若當前實例爲默認實例,則 @@SERVICENAME 返回 MSSQLServer;若當前實例是命名實例,則該函數返回實例名。

select @@spid   --返回當前用戶進程的服務器進程標識符 (ID)。

select @@servername             --返回運行 Microsoft? SQL Server? 的本地服務器名稱。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

--到目前爲止一共學了18個存儲過程,它們分別是:

Sp_dboption   --顯示或更改數據庫選項

Sp_detach_db   --分離數據庫

Sp_attach_db   --附加數據庫

Sp_addumpdevice   --添加設備

Sp_dropdevice   --刪除設備

Sp_help    --返回表的列名,數據類型,約束類型等

Sp_helpfile   --查看當前數據庫信息

Sp_helpconstraint  --返回一個列表,其內容包括所有約束類型、約束類型的用戶定義或系統提供的名稱、定義約束類型時用到的列,以及定義約束的表達式(僅適用於 DEFAULT 和 CHECK 約束)。 

Sp_helpdb   --查看指定數據庫相關文件信息

Sp_addtype    --自建數據類型

Sp_droptype    --刪除自建數據類型

Sp_pkeys    --查看主鍵

Sp_fkeys   --查看外鍵

Sp_renamedb   --更改數據庫的名稱

Sp_rename   --更改當前數據庫中用戶創建對象(如表、列或用戶定義數據類型)的名稱。

Sp_executesql N‘ ’  --執行指定的SQL命令

Sp_columns ‘表名’  --返回當前環境中可查詢的指定表或視圖的列信息。

Xp_cmdshell ‘Dos命令’  --執行指定的DOS命令

-----------------------------------------------------------------------------------------------------------------------------------------------------------

--10個日期時間函數:

Getdate()   --返回當前系統日期和時間
select getdate()

year()    --返回指定日期的年份
select year('03/12/1998')    --返回值爲1998

Month()    --返回指定日期的月份
select month('03/12/1998')      --返回值爲3

day()    --返回指定日期的天數
select day('5/10/1995')        --返回值爲10

Getutcdate()   --返回格林尼治標準時間
select getutcdate()

Datename(兩個參數)  --返回指定日期的部分字符串
select datename(hh,getdate())

Dateadd(三個參數)  --返回指定日期加上一段增量的值
select dateadd(yy,2,'5/10/1995')--返回1997-05-10

Datediff(三個參數)  --返回跨指定日期的差數
select datediff(yy,'4/6/1992','5/10/1995')--返回值3

datepart(兩個參數)  --返回指定日期指定部分的整數
select datepart(yy,'5/10/1995') --返回值爲1995

isdate()   --確定輸入表達式是否爲有效的日期
select isdate('5/10/1995')   --是日期返1,不是返0

-----------------------------------------------------------------------------------------------------------------------------------------------------------

--常用的字符串函數:

len    --返回給定字符串的字符個數
select len('accp')       --返回4

str()    --數字數據轉爲字符數據
select str('123')

ltrim()    --刪除左邊的空格
select ltrim(str('123'))

rtrim()    --刪除右邊的空格
select rtrim(str('123'))

replace()   --用第三個參數替換第一個參數所出現的第二個參數的值
select replace('ACCP','A','a')  --返回aCCP

reverse()   --反轉字符串
select reverse('ACCP')      --返回PCCA

left()    --返回從字符左邊開始指定個數的字符
select left('ACCP',2)     --返回AC

right()    --返回從字符右邊開始指定個數的字符
select right('ACCP',2)    --返回CP

lower()    --將大寫轉換爲小寫
select lower('ACCP')     --返回accp

upper()    --將小寫轉換爲大寫
select upper('accp')    --返回ACCP

ascii()    --返回字符的ASCII值(0-255)
select ascii('a')

Unicode()   --返回字符的unicode值(0-65535)
select unicode('a')

char()    --將ASCII轉換爲字符串
select char('97')

nchar()    --返回給定整數的unicode字符
select nchar('256')

 

--索引是對數據庫表中一個或多個列的值進行排序的結構
--索引提供指針以指向存儲在表中指定列的數據值,然後根據指定的排序次序排列這些指針
--sysindexes 系統表存在於每個數據庫當中,表中的 indid 字段表示索引ID,
--當它 =1時爲聚集索引,>1時爲非聚集索引,=0時說明沒有索引,=255時 具有 text 或 image 數據的表條目

--當給表創建主鍵時,自動在該列上創建聚集的唯一索引,索引名稱與主鍵名稱相同。

drop table emp

create table emp(eid int constraint pk primary key,ename varchar(10))

select *from sysindexes where name='pk'  --name的值:如果有索引則用索引名稱,沒有索引則用表的名字

--當給表添加唯一約束時,自動在該列上創建非聚集的唯一索引   

create table emp(eid int not null constraint uq unique,ename varchar(10))

select *from sysindexes where id=object_id('emp')

sp_helpindex 'emp'    --查詢指定表的索引創建在哪些列上

--只有在表上創建主鍵或唯一約束纔可以影響索引
--適合創建索引的列:1。該列頻繁使用進行搜索 2。該列用於對數據進行排序
--不適合創建索引的列:1。列中僅有幾個不同的值(低基數列)


CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ]  --創建索引的語法,[]中爲可選參數,默認爲非聚集。
 INDEX index_name
     ON table_name ( column_name [ ,column_name ]... )


create table emp(eid int not null,ename varchar(10))

create index in_name on emp(ename)  --該語句創建了非聚集非唯一的索引
      --聚集索引不一定唯一,但如果在 CLUSTERED 前加上 unique 約會則爲唯一了


--FREETEXT是個謂詞,用於搜索含有基於字符的數據類型的列,其中的值符合在搜索條件中所指定文本的含義,
--但不符合表達方式。使用 FREETEXT 時,全文查詢引擎內部將 freetext_string 拆分爲若干個搜索詞,
--並賦予每個詞以不同的加權,然後查找匹配。

--語法
FREETEXT ( { column | * } , 'freetext_string' )

--1。全文索引存放在全文目錄中
--2。當全文索引的表內容變化的時候,全文目錄必須手動更新!(選完全填充)

--示例
--使用 FREETEXT 搜索包含指定字符值的單詞
--下例搜索產品描述中含有與 bread、candy、dry 和 meat 相關的詞語的所有產品類別,如 breads、candies、dried 和 meats 等。

USE Northwind
GO
SELECT CategoryName
FROM Categories
WHERE FREETEXT (Description, 'sweetest candy bread and dry meat' )
GO

--CONTAINS一個謂詞,用於搜索包含基於字符的數據類型的列,該列與單個詞和短語,
--以及與另一個詞一定範圍之內的近似詞精確或模糊(不太精確的)匹配或者加權匹配。

--語法
CONTAINS ( { column | * } , '< contains_search_condition >')
   
--示例
--使用帶有 <simple_term> 的 CONTAINS
--下面的示例查找包含詞"bottles"且價格爲 $15.00 的所有產品。

USE Northwind
GO
SELECT ProductName
FROM Products
WHERE UnitPrice = 15.00
   AND CONTAINS(QuantityPerUnit, 'bottles')
GO


--視圖:是一張虛擬表,其內容由查詢定義。同真實的表一樣,試圖包含一系列帶有名稱的列與行數據。
--但是視圖並不在數據庫中以存儲的數據值集的形式存在。行與列數據來自由定義視圖的查詢所用的表,
--並且在引用視圖時動態生成。
--視圖中不保存數據,但是在符合一定條件的前提下可以通過視圖對基表的數據進行更新,錄入,刪除,查詢。

create table dept(did int primary key,dname varchar(10))

insert into dept select 1001,'財務部'
union select 1002,'行政部'
union select 1003,'人事部'
union select 1004,'市場部'

drop table dept

drop view a

create view a   --創建視圖的語法中必須有 AS 關鍵字
as    
select *from dept  --* 表示所有的列

--A.當視圖中包含了基表所有的非空列的時候:
--1。通過視圖向基表進行數據錄入

insert into a values(1005,'組織部')

select *from dept

--2。更新數據

update a set dname='accp' where did=1005

--3。刪除數據

delete from a where did=1005

--B.當創建的視圖沒有全部包含基表所有的非空列的時候
--1。錄入數據將失敗

alter view a    --修改視圖的語法
as
select dname from dept

insert into a values('組織部')  --這條語句將不能執行!

--2。刪除數據(當指定視圖中部分不包含的列的時候,刪除失敗;當指定視圖中包含的列的時候,刪除成功)

delete from a where dname='行政部'   

--3。更新數據(同上述要求)

update a set dname='accp' where dname='市場部'

--4。查詢數據(同上要求)

select * from a


alter view a   --修改視圖
as
select dname from dept
where did<1003   --指定視圖中只包含did<1003的部門

select *from a

--A.當創建的視圖中帶有where條件的時候(視圖中不包含基表中所有的非空列的情況)
--錄入,刪除,更新,查詢數據的時候不能指定視圖中不存在但是基表中存在的列


--B.當視圖中包含基表所有非空列時,如帶有where條件

alter view a
as
select *from dept  --用*表示包含了基表中所有非空列
where did<1003

--1。錄入數據(在創建視圖時所帶的where條件對視圖錄入數據不起作用,數據會錄入到基表中的)

insert into a values(1005,'accp')

--可以在創建視圖時加上 with check option 使where在錄入數據時也起作用

alter view a
as
select *from dept
where did<1003
with check option

--2。刪除數據與更新數據時where條件起作用

delete from a where did=1006

update a set dname='bccp' where did=1006

select *from dept


--創建多表連接視圖

create table emp
(eid int primary key,ename varchar(10),sal money default 3456,dno int references dept(did))

insert into emp values(1,'rose',default,1001)
insert into emp values(2,'jack',3,1002)
insert into emp values(3,'tom',default,1003)
insert into emp values(4,'mike',1234,1004)

drop table emp

select *from emp

create view a
as
select *from emp,dept
where emp.dno=dept.did

select *from a

--在多表視圖中錄入數據,當修改會影響到多個基表時,錄入數據會失敗。

insert into a values(5,'ekin',999,1005,1005,'bccp')

--修改不影響多個基表時,錄入數據成功

insert into a(did,dname) values(1005,'cccp')

--刪除,更新數據道理同上

--查詢數據不受限制。


--遊標語法

DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]

--全局變量 @@FETCH_STATUS 返回被FETCH語句執行的最後遊標的狀態,而不是任何當前被連接打開的遊標狀態
--它的值 =0 時,語句成功; =-1 時,語句失敗或此行不在結果集中;=-2 時被提取的行不存在。

--SCROLL關鍵字:指定所有的提取選項(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)均可用。
--如果在 SQL-92 DECLARE CURSOR 中未指定 SCROLL,則 NEXT 是唯一支持的提取選項。
--如果指定 SCROLL,則不能也指定 FAST_FORWARD。

--select_statement是定義遊標結果集的標準 SELECT 語句。
--在遊標聲明的 select_statement 內不允許使用關鍵字 COMPUTE、COMPUTE BY、FOR BROWSE 和 INTO。

--遊標過程舉例

declare cr scroll cursor  --遊標的聲明
for
select *from emp   
open cr     --打開遊標
fetch last from cr   --遊標的推進
close cr    --關閉遊標
deallocate cr    --釋放遊標


select *from emp where 1>2
select @@error    --用 @@error 判斷sql語句是否正確執行

select @@rowcount   --受上一sql語句影響的函數。它的值若爲-則表示不返回任何行


declare employee_cursor cursor
for
select lastname,firstname
from employees for update of lastname
open employee_cursor
fetch next from employee_cursor
while @@fetch_status=0
begin
fetch next from employee_cursor
update employees set firstname='jack' where 1>2
end
close employee_cursor
deallocate employee_cursor

--以上程序爲遊標應用的更新。從上往下的第四行表示只能更新lastname.
--(實際此例並不是真正通過遊標進行更新的!)

begin tran
declare employee_cursor cursor
for
select lastname,firstname
from employees for update of lastname
open employee_cursor
fetch next from employee_cursor
while @@fetch_status=0
begin
fetch next from employee_cursor
update employees set firstname='jack'
where current of employee_cursor  --通過這個where來實現真正的遊標更新
end
close employee_cursor
deallocate employee_cursor
rollback


declare employee_cursor cursor
for
select lastname,firstname
from employees
open employee_cursor
fetch next from employee_cursor
while @@fetch_status=0
begin
fetch next from employee_cursor
delete from employees    --通過遊標刪除數據
where current of employee_cursor
end
close employee_cursor
deallocate employee_cursor

select *from employees

-----------------------------------------------------------------------------------------------------

--存儲過程

create proc p1    --這程序本意是讓@a1與@a2的值進行交換,
@a int,@b int    --但結果並非如此,因爲向過程傳遞參數時用的是值傳遞。
as
begin
declare @temp int
set @temp=@a
set @a=@b
set @b=@temp
end

declare @a1 int,@a2 int
set @a1=1
set @a2=2
EXEC p1 @a1,@a2
print @a1
print @a2


alter proc p1    --修改一個過程
@a int output,@b int output  --用output可以實現按地址傳遞
as
begin
declare @temp int
set @temp=@a
set @a=@b
set @b=@temp
end

declare @a1 int,@a2 int
set @a1=1
set @a2=2
EXEC p1 @a1 output,@a2 output  --向過程傳遞參數時也要用output
print @a1
print @a2


alter proc p1
@a int,@b int    --一個過程的返回值不能通過參數列表看出來
as
begin
if(@a>@b) return 0   --用return表示返回值,該返回值描述一種狀態
return -1
end

declare @res int   --變量@res用來保存返回值
EXEC @res=p1 1,3
print @res


alter proc p1    --結合表的存儲過程
as
begin
declare @tab table(eid int)
insert into @tab select eid from emp
select * from @tab
end

exec p1


alter proc p1
@a int=90,@b int   --存儲過程參數有默認值的情況
as
begin
declare @c int
select @c=@a+@b
print @c
end         --參數有默認值時傳遞參數有以下兩種方式
    
exec p1 default,10   --1。使用 fefault 傳遞 

exec p1 @b=10    --2。使用定義時的參數名稱傳遞

------------------------------------------------------------------------------------------------------------]

--觸發器是一種特殊類型的存儲過程,不由用戶直接調用。創建觸發器時會對其進行定義,以便在對特定表或列作特定類型的數據修改時執行。


create trigger tr   --tr爲觸發器名稱
on emp for insert   --insert 爲指定的觸發動作,其他動作還有:delete,update,多個動作之間用逗號分隔
as
begin     --begin 與 and 之間爲觸發器語句主題,其內部可以用事務控制語句
print '不能錄入數據!'
rollback
end     --同一個動作可以定義多個觸發器,但其執行的次序是隨機的


insert into emp select 1001,'rose',2005 --用這條語句錄入數據時觸發器只觸發一次 ,insert觸發器觸發幾次要看有多少insert語句
 union select 1002,'jack',2006


--邏輯表 inserted介紹
     
--錄入數據時,數據首先會被存放在inserted邏輯表中,接着等待用戶回退或提交的命令,
--如果用戶回退,則清空該表數據;如果用戶提交,則將該表數據永遠寫入數據庫

--邏輯表結構與觸發器結構完全相同,存在於內存中。邏輯表主要用來做數據的審計。

select *into audit_emp from emp where 1>2   --audit_emp表爲用來審計的表
alter table audit_emp add descr varchar(20) default '錄入數據'


alter trigger tr
on emp for insert
as
begin
print '錄入數據'
insert into audit_emp(eid,ename,sal) select *from inserted 
end

--邏輯表 deleted 介紹

--結構和觸發器表的結構完全相同,當刪除數據的時候該數據首先會被放在deleted邏輯表中,接着等待用戶提交或回退命令,
--如果提交則清空該表數據,如果用戶回退,則把該表數據放回原處,以保證了數據的一致性

--刪除動作不涉及 inserted,錄入動作也不涉及 deleted 。


--update 動作發生的時候,歷史數據首先會被放在deleted表中,新數據會被放在inserted表中,接着等待用戶提交或回退命令。
--如果用戶提交,則新數據從inserted表中錄入,並同時清空deleted表;如果回退,則將的deleted表中數據恢復,同時清空inserted表。

 

--使用 OUTPUT 遊標參數
OUTPUT 遊標參數用來將存儲過程的局部遊標傳遞迴調用批處理、存儲過程或觸發器。

首先,創建以下過程,在 titles 表上聲明並打開一個遊標:

USE pubs
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'titles_cursor' and type = 'P')
DROP PROCEDURE titles_cursor
GO
CREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUT
AS
SET @titles_cursor = CURSOR
FORWARD_ONLY STATIC FOR
SELECT *
FROM titles

OPEN @titles_cursor
GO

接下來,執行一個批處理,聲明一個局部遊標變量,執行上述過程以將遊標賦值給局部變量,然後從該遊標提取行。

USE pubs
GO
DECLARE @MyCursor CURSOR
EXEC titles_cursor @titles_cursor = @MyCursor OUTPUT
WHILE (@@FETCH_STATUS = 0)
BEGIN
   FETCH NEXT FROM @MyCursor
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO


--存儲過程、函數、視圖和觸發器定義
在 syscomments 系統表中保存存儲過程、函數、觸發器或視圖的定義時,可以對其進行加密(例如,如果 SQL Server 系統包含專有的存儲過程、函數、觸發器或視圖,則其定義不應由用戶和第三方查看)。

--使用 WITH ENCRYPTION 選項
WITH ENCRYPTION 子句對用戶隱藏存儲過程的文本。下例創建加密過程,使用 sp_helptext 系統存儲過程獲取關於加密過程的信息,然後嘗試直接從 syscomments 表中獲取關於該過程的信息。

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'encrypt_this' AND type = 'P')
   DROP PROCEDURE encrypt_this
GO
USE pubs
GO
CREATE PROCEDURE encrypt_this
WITH ENCRYPTION
AS
SELECT *
FROM authors
GO

EXEC sp_helptext encrypt_this

下面是結果集:

The object's comments have been encrypted.

接下來,選擇加密存儲過程內容的標識號和文本。

SELECT c.id, c.text
FROM syscomments c INNER JOIN sysobjects o
   ON c.id = o.id
WHERE o.name = 'encrypt_this'
下面是結果集:

說明  text 列的輸出顯示在單獨一行中。執行時,該信息將與 id 列信息出現在同一行中。


id         text                                                       
---------- ------------------------------------------------------------
1413580074 ?????????????????????????????????e??????????????????????????????????????????????????????????????????????????

(1 row(s) affected)

--觸發器加密同存儲過程加密

CREATE TRIGGER trigger_name
ON { table | view }
[ WITH ENCRYPTION ]    --在這爲觸發器加密
{
    { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] }
        [ WITH APPEND ]
        [ NOT FOR REPLICATION ]
        AS
        [ { IF UPDATE ( column )
            [ { AND | OR } UPDATE ( column ) ]
                [ ...n ]
        | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
                { comparison_operator } column_bitmask [ ...n ]
        } ]
        sql_statement [ ...n ]
    }
}

--加密視圖
下例使用 WITH ENCRYPTION 選項並顯示計算列、重命名列以及多列。

USE pubs
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
      WHERE TABLE_NAME = 'accounts')
   DROP VIEW accounts
GO
CREATE VIEW accounts (title, advance, amt_due)
WITH ENCRYPTION
AS
SELECT title, advance, price * royalty * ytd_sales
FROM titles
WHERE price > $5
GO


--創建用戶自定義函數

--語法
--標量函數

CREATE FUNCTION [ owner_name.] function_name
    ( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )

RETURNS scalar_return_data_type

[ WITH < function_option> [ [,] ...n] ]

[ AS ]

BEGIN
    function_body
    RETURN scalar_expression
END

--內嵌表值函數

CREATE FUNCTION [ owner_name.] function_name
    ( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )

RETURNS TABLE

[ WITH < function_option > [ [,] ...n ] ]

[ AS ]

RETURN [ ( ] select-stmt [ ) ]

--多語句表值函數

CREATE FUNCTION [ owner_name.] function_name
    ( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )

RETURNS @return_variable TABLE < table_type_definition >

[ WITH < function_option > [ [,] ...n ] ]

[ AS ]

BEGIN
    function_body
    RETURN
END

< function_option > ::=
    { ENCRYPTION | SCHEMABINDING }  --爲函數加密

< table_type_definition > ::=
    ( { column_definition | table_constraint } [ ,...n ] )

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章