關於SQL SERVER數據庫學習總結


  對於SQL SERFVER數據庫也學了有一陣子了,自己也對自己所學做了一些總結。

   我們首先學習數據庫設計的一些知識點和用SQL語句建庫。

  設計數據庫步驟:需求分析階段,概要設計階段,詳細設計階段,

   建數據庫的SQL語句如下(包含了如果有該數據庫先刪除在建立數據庫)

use master
GO
if exists(select * from sysdatabases where name='Wages')
DROP database Wages
CREATE DATABASE Wages
 ON
 (
  NAME='Wages_data',
  FILENAME='e:\project\Wages_data.mdf',
  SIZE=5mb,
  FILEGROWTH=15%
 )
 LOG ON
 (
  NAME= 'Wages_log',
  FILENAME='e:\project\Wages_log.ldf',
  SIZE=3mb,
  FILEGROWTH=15%
 )
GO

為了創建良好的數據庫需滿足三大范式。

下面是創建表的SQL語句(包含了如果有該表先刪除在建表)

USE Wages
GO
if exists(select * from sysobjects where name='WageInfo')
DROP table WageInfo
CREATE TABLE WageInfo 
(
  CompanyID INT primary key IDENTITY(1,1),
  CompanyName varchar(50) NOT NULL,
  Poste varchar(50) NOT NULL,
)
GO
if exists(select * from sysobjects where name='StudentInfo')
DROP table StudentInfo
CREATE TABLE StudentInfo
(
  ID  INT primary key IDENTITY(1,1),
  Name  VARCHAR(50) NOT NULL,
  CompanyID INT ,
  PosteDate  DATETIME ,
  Wage  int,
)
GO

下面是創建約束

語法如下

alter table 表名

add constraint 約束名 約束類型 具體的約束說明

示例

創建外鍵約束

alter table StudentInfo
add constraint pk_CompanyID foreign key(CompanyID) references WageInfo(CompanyID)
GO

插入數據語句如下

insert into WageInfo(CompanyName, Poste)values
('微軟','職員'),
('百度','職員'),
('騰訊','職員'),
('愛奇藝','職員'),
('華為','職員')
insert into StudentInfo(Name, CompanyID, PosteDate, Wage)values
('張三',1,'2016-05-05',2500),
('李四',2,'2016-05-06',2600),
('王五',3,'2016-05-07',3000),
('趙二',4,'2016-05-08',4000),
('錢一',5,'2016-05-09',5000)
insert into StudentInfo(Name, CompanyID, PosteDate, Wage)values('錢二',null,'2016-05-09',NULL)

然后我們學習了變量,變量分全局變量和局部變量。

創建變量語法如下是

declare @變量名 數據類型

局部變量有兩種賦值方法

set @變量名=value

select @變量名=value

區別是select可一次對多個變量賦值,set只能一次對一個變量賦值。

全局變量只能用不能自己創建和賦值!!!

輸出語句

print 和select

use MySchool

go

select * from StuInfos

1.班級表   班級編號 (主鍵)   班級名   (長度固定3位)   班級人數 (默認30)

  if exists(select * from sysobjects where name='Classes')

drop table Classes

  go  

 create table Classes  

 (   clsid int identity(1,1), --班級編號  

' clsname varchar(3), --班級名稱   clsnums int --班級人數   )   

go   

'alter table Classes

add constraint pk_clsid_Classes   primary key(clsid)  

 alter table Classes

add constraint ck_clsname_Classes   check(len(clsname)=3)  

 alter table Classes

add constraint df_clsnums_Classes   default 30 for clsnums   

go  

 insert into Classes select 't10',25 union select 't11',18 union select 't12',23

2.外鍵約束   為學生表添加一個clsid列來表示其班級   alter table StuInfos add clsid int   外鍵約束   

alter table StuInfos with nocheck --不對表現有的數據作限制操作

add constraint fk_StuInfos_Classes    foreign key(clsid) references Classes(clsid)   

刪除約束   

alter table StuInfos drop constraint fk_StuInfos_Classes

3.建表同時建約束,老師表   編號     (主鍵 標識列)   名稱     (非空)

性別     (男或女,默認男)   年齡     (12-60)   電話     (唯一)   班級編號 (外鍵)   

if exists(select * from sysobjects where name='TeaInfos')

drop table TeaInfos  

 go  

 create table TeaInfos  

 ( id int primary key identity(1,1), --編號

name varchar(10) not null, --名稱

sex char(2) check(sex='男' or sex='女') default '男', --性別

age int check(age>=12 and age<=60), --年齡

tel char(11) unique, --電話

clsid int foreign key references Classes(clsid) --班級   )

  go

一:操作變量 --1-- 聲明變量@temp值為1並打印出來 聲明變量關鍵字:

declare   declare @temp int --聲明   

set @temp=1       --賦值  

 print @temp       --輸出   

  declare @temp int=1 --聲明的同時賦值  

 print @temp         --輸出   

 

賦值方式一:用set 輸出方式一:用print   declare @temp int --聲明   

select @temp=1 --賦值   select @temp   --輸出

賦值方式二:用select 輸出方式二:用select --

2-- 聲明三個變量存儲'姓名、性別、年齡',再打印信息,格式如下: 姓名:傑達姆,性別:男,年齡:18 --聲明

declare @name varchar(10),         @sex char(2),         @age int

--賦值 select @name='傑達姆',@sex='男',@age=18

--輸出 print  '姓名:'+@name+',性別:'+@sex+',年齡:'   +cast(@age as varchar)   

--convert(varchar,@age)

--兩個轉型函數:   1.convert -- 語法:  convert(類型,數據)   2.cast   

-- 語法:  case(數據 as 類型)

--3-- select * from StuInfo

打印張秋麗的信息(來自於student數據庫的數據),格式如下: 姓名:張秋麗 性別:男 年齡:18

--聲明 declare  @name varchar(10)='張秋麗', @sex char(2), @age int

--賦值:來自於表內 select @sex=stuSex,@age=stuAge from stuinfo  where stuName=@name

--輸出 print '姓名:'+@name print '性別:'+@sex print '年齡:'+cast(@age as varchar)

--4-- 查詢李文才的左右同桌的信息 declare @seat int select @seat=stuSeat from stuinfo where stuname='李文才' select * from stuinfo  where stuSeat=@seat-1 or stuSeat=@seat+1

--5-- 查詢比張秋麗大10歲以上的學生信息 declare @age int  select @age=stuAge from stuinfo where stuName='張秋麗' select * from stuinfo where stuAge>=10+@age 

總結: set和select的區別  

 1. set一次只能為一個變量賦值,而select能同時為多個變量賦值  

 2. set只能賦一個固定的值,而select能動態的賦值(值來自於表內) select的作用  

 1. 查詢SQL語句,如: select * from 表名  

 2. 賦值操作,   如: select 變量名=值  

 3. 輸出操作,   如: select 變量名 二:控制流程結構:if,else

--1-- 聲明變量number,並賦值,然后判斷是偶數還是奇數,結果如下: 當前值為11,它是一個奇數 declare @number int set @number=12 if(@number%2=0) print '該數為偶數' else print '該數為奇數' -

-2-- 根據輸入的年齡顯示人的生長階段 未成年人<18,青年人<30,成年人<60,老年人<100,超人>=100

declare @age int set @age=21

if(@age<18) print '未成年人' else if(@age<30)

print '青年人'

else if(@age<60)

print '成年人'

else if(@age<100)

print '老年人'

else print '超人'

select * from StuInfo select * from StuExam

--3-- 統計筆試平均分,如果平均分超過70分打印'優秀' 同時顯示前三名學員的考試信息否則      打印'較差'顯示后三名學生信息

declare @avgScore int select @avgScore=AVG(writtenExam) from StuExam if(@avgScore>=70) begin print '本班成績優秀'

select top 3 * from StuExam order by writtenExam desc end else begin print '本班成績較差' select top 3 * from StuExam order by writtenExam end

三:循環結構 --1-- 輸出九九次'我愛你' declare @i int=1  while(@i<=99) begin print '第'+convert(varchar,@i)+'我愛你' set @i+=1 end

--2-- 計算1-100的累加和,結果格式:1-100的累加和為:xxx declare  @i int=1, @sum int=0 while(@i<=100) begin set @sum+=@i set @i+=1 end print '1-100的累加和為:'+convert(varchar,@sum)

--3-- 不停的提高學生筆試成績2分,讓所有學生的筆試成績都及格

declare @count int --用來記錄不及格的人數 while(1=1) begin --計算不及格的人數 select @count=COUNT(*) from StuExam   where writtenExam<60 --判斷 if(@count=0)   break --退出死循環 else   update StuExam set writtenExam+=2 end select * from StuExam

四:多分支語句

--1-- 請聲明變量@name表示學生姓名,對該學生年齡進行划等級 具體如下: 12歲前顯示:'小學生' 12-17顯示'初中生'  18-22顯示'高中生' 23-28顯示'大學生' 28以上'超人' 結果格式:xxx是一個xxx

declare  @name varchar(20)='小強', @age int=23, @result varchar(10)

--多分支 set @result=case     when @age<12 then '小學生'     when @age<17 then '初中生'     when @age<22 then '高中生'     when @age<28 then '大學生'     else '超人'    end

--輸出 print @name+'是一個'+@result

--2-- 顯示學號、筆試成績、等級,數據如下:  筆試成績:90以上的--A等         80以上的-- B等         70以上的-- C等         60以上的-- D等         60以下的-- E等 stuNo   writtenExam   grade s25303  60            D等 s25302  40            E等 s25301  77            C等 s25318  45            E等 select  stuNo, writtenExam, grade=case    when writtenExam>=90 then 'A等'    when writtenExam>=80 then 'B等'    when writtenExam>=70 then 'C等'    when writtenExam>=60 then 'D等'    else 'E等'     end from StuExam --3-- 請根據平均分和下面的評分規則,編寫T-SQL語句查詢學員的成績 優 :90分以上    良 :80-89分     中 :70-79分     差 :60-69分     極差 :60分以下         

select AVG(writtenExam),A=case      when Avg(writtenExam)>90 then '優'      when Avg(writtenExam)>80 and Avg(writtenExam)<89 then '良'      when Avg(writtenExam)>70 and Avg(writtenExam)<79 THEN '中'      when Avg(writtenExam)>60 and Avg(writtenExam)<69 then '差'      when Avg(writtenExam)<60 then '極差'      end      from stuExam    

--4-- 問題: 根據如下規則對機試成績進行反復加分,       直到機試平均分超過85分為止       請編寫T-SQL語句實現,注:(循環+多分支) 90分以上:  不加分 80-89分:   加1分 70-79分:   加2分 60-69分:   加3分 60分以下:  加5分 declare @a int   while(1=1) begin select @a=AVG(labExam)from dbo.stuExam if(@a<85) begin update dbo.stuExam set labExam =case          when labExam>=90 then  labExam          when labExam>=80 then labExam+1          when labExam>=70 then labExam+2          when labExam>=60 then labExam+3          else          labExam+5         end end else break end select AVG(labExam) AS 機試成績平均分 from dbo.stuExam

查詢

子查詢:查詢中再查詢,通常是以一個查詢作為條件來供另一個查詢使用
語法:
   select 列表 from 表名 
 where >(子查詢)
注意:
 使用比較運算符時,要求子查詢只能返回一條或空的記錄!
示例:
 要求查出比我小的學生信息
 select * from student
 where studentno in
 (select studentno from student
 where studentname='我')

NOT IN:確定給定的值是否與子查詢或列表中的值相匹配,如果不匹配則反回真。
使用方法:
 在需要子查詢返回多數據時使用。
語法:
 select 列表 from 表名 
 where 列名 not in(子查詢)
示例:
 查詢未參加過考試的學生信息
 select  * from student 
 where studentno not in
 (select studentno from Result)

1.EXISTS 子查詢
 EXISTS: exists 關鍵字能夠檢測數據是否存在,如果存在返回真。
語法
 if exists(子查詢)
 語句
示例:
 查詢本校學生有沒有叫張三的
 if exists( select * from student
 where studentname='張三' )
 begin
 print '有叫張三的'
 end

2. NOT EXISTS 子查詢
 NOT EXISTS: exists 關鍵字能夠檢測數據是否存在,如果不存在返回真
語法
 if not exists(子查詢)
 語句
示例:
 查詢本校學生是不是沒有叫張三的
 if not exists( select * from student
 where studentname='張三' )
 begin
 print '沒有叫張三的'
 end

1:非相關子查詢是獨立於外部查詢的子查詢,子查詢總共執行一次,執行完畢后將值傳遞給外部查詢。  2:相關子查詢的執行依賴於外部查詢的數據,外部查詢執行一行,子查詢就執行一次。數據是否存在,如果不存在返回真

示例:檢索出在work表中每一個部門的最高基本工資的職工資料  select * from work a where 基本工資=(select max(基本工資) from work b where a.部門名稱=b.部門名稱)

 事物視圖索引

語法

begin transaction

commit transaction

rollback transaction

視圖

創建視圖索引

if exists(select * from sysobjects where name='視圖名')

drop view 視圖名

create view  視圖名

as

SQL語句

索引

if exists(select name from sysindex where name='索引')

drop index 表名。索引名

create 索引類型 index 索引名

on 表名(列名)

with fillfactor=30

GO

一 存儲過程的概念

存儲過程是在數據庫管理系統保存的,預先編譯的,能實現某種功能的SQL程序,它是數據庫應用中運用比較廣泛的一種數據對象。

為什么需要存儲過程?

1.存儲過程只在創造時進行編譯,以后每次執行存儲過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。 2.當對數據庫進行復雜操作時,可將此復雜操作用存儲過程封裝起來與數據庫提供的事務處理結合一起使用。 3.存儲過程可以重復使用,可減少數據庫開發人員的工作量。 4.安全性高,可設定只有某些用戶才具有對指定存儲過程的使用權

存儲過程的優點:

1.模塊化程序設計

2.執行速度塊,效率高

3.減少網絡流量

4.具有良好的安全性

 

二 系統存儲過程

SQL_SERVER 提供系統存儲過程,它們是一組預編譯的T-SQL語句,系統存儲過程提供了管理數據庫和更新表的機制,並充當從系統表中檢索信息的快捷方式。

常用的系統存儲過程

系統存儲過程

說明

sp_databases

列出服務上的所有數據庫

sp_helpdb

報告有關指定數據庫或所有數據庫的信息

sp_renamedb

更改數據庫的名稱

sp_tables

返回當前環境下可查詢的對象的列表

sp_columns

返回某個表列的信息

sp_help

返回某個表的所有信息

sp_helpconstraint

查看某個表的約束

sp_helpindex

查看某個表的索引

sp_stored_procedures

列出當前環境中的所有存儲過程

sp_password

添加或修改登錄賬戶的密碼

 

三 用戶自定義的存儲過程

1.創建不帶參數的存儲過程

Create proc usp_selectstu

As

Select StudentName,Gender,GradeId,Phone from dbo.Student

 

調用存儲過程:exec usp_selectstu

2.創建帶入參數的存儲過程

Create proc usp_stuInfo @gradeid int=2       (默認)

As

Select * from student where gradeId=@gradeid

調用存儲過程:exec usp_stuInfo 2

3.創建帶出參數的存儲過程

create proc usp_selectGrade @name nvarchar(10),@gradeid int output

As

Select @gradeid=gradeid from student where  studentname=@name

print @gradeid

 

調用存儲過程:

declare @id int

exec usp_selectGrade '李小龍',@id output 

 

  4、 帶通配符參數存儲過程

Create proc usp_one  @name nvarchar(10)

as

select * from dbo.Student where StudentName like @name

 

exec usp_one '%'

   5、 不緩存存儲過程

緩存就是數據交換的緩沖區(稱作Cache),當某一硬件要讀取數據時,會首先從緩存中查找需要的數據,如果找到了則直接執行,找不到的話則從內存中找。由於緩存的運行速度比內存快得多,故緩存的作用就是幫助硬件更快地運行。

Sql Server系統內存管理在沒有配置內存最大值,很多時候我們會發現運行Sql Server的系統內存往往居高不下。這是由於他對於內存使用的策略是有多少閑置的內存就占用多少,直到內存使用慮達到系統峰值時(預留內存根據系統默認預留使用為准,至少4M),才會清除一些緩存釋放少量的內存為新的緩存騰出空間。

這些內存一般都是Sql Server運行時候用作緩存的,例如你運行一個select語句, 執行個存儲過程,調用函數;

1. 數據緩存:執行個查詢語句,Sql Server會將相關的數據頁(Sql Server操作的數據都是以頁為單位的)加載到內存中來,下一次如果再次請求此頁的數據的時候,就無需讀取磁盤了,大大提高了速度。

2.執行命令緩存:在執行存儲過程,自定函數時,Sql Server需要先二進制編譯再運行,編譯后的結果也會緩存起來, 再次調用時就無需再次編譯。

 

create proc proc_temp with recompile as     select * from student exec proc_temp

 

6加密存儲過程

exec sp_helptext 儲存過程名      可以查看儲存過程代碼

create proc proc_temp_encryption

with encryption

as

    select * from student;

go

--存儲過程的內容不會被輕易看到(雖然解密也是有可能的)。

--應用這個,我們可以對某些關鍵的存儲過程進行加密。

--但此時,存儲過程仍然能被executealterdrop

exec proc_temp_encryption;

exec sp_helptext 'proc_temp'

exec sp_helptext 'proc_temp_encryption'

(注意:加密存儲過程前應該備份原始存儲過程,且加密應該在部署到生產環境前完成。) 

 

一 存儲過程的概念

存儲過程是在數據庫管理系統保存的,預先編譯的,能實現某種功能的SQL程序,它是數據庫應用中運用比較廣泛的一種數據對象。

為什么需要存儲過程?

1.存儲過程只在創造時進行編譯,以后每次執行存儲過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。 2.當對數據庫進行復雜操作時,可將此復雜操作用存儲過程封裝起來與數據庫提供的事務處理結合一起使用。 3.存儲過程可以重復使用,可減少數據庫開發人員的工作量。 4.安全性高,可設定只有某些用戶才具有對指定存儲過程的使用權

存儲過程的優點:

1.模塊化程序設計

2.執行速度塊,效率高

3.減少網絡流量

4.具有良好的安全性

 

二 系統存儲過程

SQL_SERVER 提供系統存儲過程,它們是一組預編譯的T-SQL語句,系統存儲過程提供了管理數據庫和更新表的機制,並充當從系統表中檢索信息的快捷方式。

常用的系統存儲過程

系統存儲過程

說明

sp_databases

列出服務上的所有數據庫

sp_helpdb

報告有關指定數據庫或所有數據庫的信息

sp_renamedb

更改數據庫的名稱

sp_tables

返回當前環境下可查詢的對象的列表

sp_columns

返回某個表列的信息

sp_help

返回某個表的所有信息

sp_helpconstraint

查看某個表的約束

sp_helpindex

查看某個表的索引

sp_stored_procedures

列出當前環境中的所有存儲過程

sp_password

添加或修改登錄賬戶的密碼

 

三 用戶自定義的存儲過程

1.創建不帶參數的存儲過程

Create proc usp_selectstu

As

Select StudentName,Gender,GradeId,Phone from dbo.Student

 

調用存儲過程:exec usp_selectstu

2.創建帶入參數的存儲過程

Create proc usp_stuInfo @gradeid int=2       (默認)

As

Select * from student where gradeId=@gradeid

調用存儲過程:exec usp_stuInfo 2

3.創建帶出參數的存儲過程

create proc usp_selectGrade @name nvarchar(10),@gradeid int output

As

Select @gradeid=gradeid from student where  studentname=@name

print @gradeid

 

調用存儲過程:

declare @id int

exec usp_selectGrade '李小龍',@id output 

 

  4、 帶通配符參數存儲過程

Create proc usp_one  @name nvarchar(10)

as

select * from dbo.Student where StudentName like @name

 

exec usp_one '%'

   5、 不緩存存儲過程

緩存就是數據交換的緩沖區(稱作Cache),當某一硬件要讀取數據時,會首先從緩存中查找需要的數據,如果找到了則直接執行,找不到的話則從內存中找。由於緩存的運行速度比內存快得多,故緩存的作用就是幫助硬件更快地運行。

Sql Server系統內存管理在沒有配置內存最大值,很多時候我們會發現運行Sql Server的系統內存往往居高不下。這是由於他對於內存使用的策略是有多少閑置的內存就占用多少,直到內存使用慮達到系統峰值時(預留內存根據系統默認預留使用為准,至少4M),才會清除一些緩存釋放少量的內存為新的緩存騰出空間。

這些內存一般都是Sql Server運行時候用作緩存的,例如你運行一個select語句, 執行個存儲過程,調用函數;

1. 數據緩存:執行個查詢語句,Sql Server會將相關的數據頁(Sql Server操作的數據都是以頁為單位的)加載到內存中來,下一次如果再次請求此頁的數據的時候,就無需讀取磁盤了,大大提高了速度。

2.執行命令緩存:在執行存儲過程,自定函數時,Sql Server需要先二進制編譯再運行,編譯后的結果也會緩存起來, 再次調用時就無需再次編譯。

 

create proc proc_temp with recompile as     select * from student exec proc_temp

 

6加密存儲過程

exec sp_helptext 儲存過程名      可以查看儲存過程代碼

create proc proc_temp_encryption

with encryption

as

    select * from student;

go

--存儲過程的內容不會被輕易看到(雖然解密也是有可能的)。

--應用這個,我們可以對某些關鍵的存儲過程進行加密。

--但此時,存儲過程仍然能被executealterdrop

exec proc_temp_encryption;

exec sp_helptext 'proc_temp'

exec sp_helptext 'proc_temp_encryption'

(注意:加密存儲過程前應該備份原始存儲過程,且加密應該在部署到生產環境前完成。) 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM