T-SQL 基本語法

--查詢
select DB_ID('B2C') 

--檢查數據庫是否存在
if DB_ID('B2C') is not null

--使用數據庫
use B2C 

--單引號表示字符串,雙引號則不是 U 表示用戶表
select OBJECT_ID('UserName','U')  
--主鍵約束Primary key 
--惟一約束Unique
--外鍵約束foreign key () references 
--檢查約束Check
--非空約束

--Select 語句的元素
--From
--Where
--Group by
--Having
--Select
--Order by

--表達式
select  orderdate,year(orderdate) as 訂單年份
from Orders;
--選擇
select orderdate,year(orderdate) as 訂單年份
from Orders
where year(orderdate)=2006

--查詢同一年出生的員工人數
select YEAR(birthdate),COUNT(*)
from Employee
group by YEAR(birthdate)

--百分比
select top (20) percent lastname,firstname
from hr.employees

--開窗函數 over 
select lastname,firstname,count(*) over ()
from hr.employees

--帶有總價的訂單
--partition by  至關於作一個相對的選擇,選出等於的值
select lastname,firstname,val
,sum(val) over( partition by custid) as 顧客總價
,sum(val) over() as 總價
from Sales.OrderValues

--排名函數
--row_number 行號  必須與 over 配合
--rank       排名
--dense_rank 密集排名
--ntile      分組
select row_number() over( order by lastname ),lastname,firstname
       rank()       over( order by country) as 排名,
       dense_rank() over( order by country) as 密集排名,
       ntile(5)     over( order by country) as 分組,
from hr.employees

--排名結合部分
select row_number() over( order by country)
       row_number() over( partition by country order by country),
       country,lastname,firstname
      from hr.employees

--between and 
select *
from OrderValues
where val between 1000 and 200

--in 枚舉值
select *
from OrderValues
where custid in (1,2,8)

--like 字符串匹配  % 任意多個任意字符  _任意一個任意字符

--簡單表達式
select lastname,region,
 case  region          -switch 
       when 'WA' then '華盛頓'   --case 
       else '其餘特區'
  end
from employees

--搜索表達式
select lastname,region,
case 
     when region='WA' then '華盛頓特區'
     when region is null then '位置地區'
     else '其它地區'
end
from employees;

--定義變量
declare @s char(10),
--賦值以後,實際上已經填滿了10個字符
set @s='hello'
print @s
set @s = @s+'world'
print @s

--注意:在SQL 中,下標從1開始
select productname,substring(productname,9,10)
from production.Products

--left 表示左邊
select productname, left(productname,8)
from production.Products

--right 表示取右邊的部分
select productname,right(productname,8)
from production.Products

--模版在前,源字符串在後,空格出如今名字中的位置,從1開始
select productname,charindex('',productname)
from production.Products

--將產品名稱中的product 替換爲產品名
select productname,replace(productname,'Product','產品名')
from production.Products

--stuff 替換
select productname,stuff(productname,8,1,' : ')
from production.Products

--轉換大寫 和 小寫
select productname,upper(productname),lower(productname)
from production.Products

--去空格
select  datalength(rtrim(string))
select ltrim(rtrim(string))

--字符串方式表示日期
select orderid,orderdate 
from Sales.orders
where orderdate > '20080301'

--cast 轉換 datetime   這個和上面一個是等價的
select orderid,orderdate
from Sales.orders
where orderdate > cast ('20080301' as datetime)

-- datepart 取日期中的一部分
select getdate()

--年,月,日,小時,分鐘,秒
select datepart(year,getdate()),
       datepart(month,getdate()),
       datepart(day,getdate()),
       datepart(hour,getdate()),
       datepart(minute,getdate()),
       datepart(second,getdate()
       
--特殊
select datepart(dayofyear,getdate()),-- 從年初到如今的天數
       datepart(weekday,getdate()),--星期幾,從星期天開始爲1
       datepart(week,getdate()) --今年的第幾周

select year(getdate()),month(getdate()),day(getdate()

--日期加和減  日期加法 單位
select getdate(),dateadd(month,2,getdate()) -- 加兩個月
       dateadd(year,3,getdate()),
       dateadd(minute,30,getdate())
       
--日期減法 單位
select datediff(year,'19491001',getdate())

--計算今年多少歲
select datediff(year,'19800101',getdate())

--練習1
select *
from Sales.Orders
where year(orderdate)=2007 and month(orderdate)=7

select *
from Sales.Orders
where datepart(year,orderdate)=2007 and
      datepart(month,orderdate)=6
--還能夠 '200706'
--將日期轉換成字符串
select *
from Sales.Orders
where left(convert(nvarchar,(orderdate),112),6)='200706'

select getdate(),convert(nvarchar,getdate(),112),
       left(convert(nvarchar,getdate(),112),6)
       
select convert(int,'99')+100
select cast('99' as int)+100

select orderid,sum(unitprice * qty)
from Sales.Orderdatails
group by orderid
having sum(unitprice *qty) >10000
order by sum(unitprice * qty) desc

--3-1交叉鏈接和內鏈接
--鏈接查詢  cross 翻譯十字   因此的都作了一次匹配
select empid,shipperid
from Hr.employees cross join Sales.Shippers

--內鏈接  必須符合特定條件的組合
select c.categoryid,productid,p.productname,c.categoryname
from production.Categories c inner join production.products p
on c.categoryid=p.categoryid

--查詢每一個顧客的名稱,已經下過多少張訂單
select distinct c.custid,contactname,orderid,
       count(*) over(partition by o.custid)
       from Sales.Customers c inner join Sales.Orders o
       on c.custid=o.custid
       
--插入10 條記錄
insert into digits (digit)
values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

--生成數字
select d1.digit,d2.digit, d3.digit* 10 + d2.digit*10 +d1.digit
from digits di cross join digits d2
  cross join digits d3

--實現1-1000
select row_number() over(order by d1.digit) as digit
from digits d1 cross join digits d2
     cross join digits d3
     order by digit

--查詢每張訂單多少錢
select distinct o.orderid,orderdate,
     sum(qty * unitprice) over(partition by o.orderid)
from Sales.Orders o inner join Sales.OrderDatails d
on o.orderid=d.orderid

--左外鏈接
select count(*)
from Sales.Customers c left outer join Sales.Order o
on c.sutid =o.custid

--右外鏈接
select count(*)
from Sales.Customers c right outer join Sales.Order o
on c.sutid =o.custid

--組函數不包含 Null
select  distinct c.contactname,
count(o.orderid) over(partition by c.custid)  ordercount
from Sales.Customers c left outer join Sales.Orders o
on c.custid=o.custid
order by ordercount

--查詢一下全部的僱員都處理過訂單
 select e.empid,count(o.orderid),lastname
 from hr.employee e left outer join sales.orders o
      on e.empid=o.empid
group by e.empid,lastname
having count(o.orderid)=0

--將員工表和訂單表作一個外鏈接
select e.empid,e.lastname
from left outer join sales.orders o
where o.orderis is null

--查詢有顧客可是沒有供應商的國家
select distinct c.country as 客戶國家,s.country as 供應商國家
from Sales.Customers c left outer join Production.Suppliers s
     on c.country=s.country
where c.country is null

--全外鏈接,查詢全部的國家,有無供應商,有無顧客
select distinct c.country as 客戶國家,s.country as 供應商國家
from Sales.Customers c full outer join Production.Suppliers s
    on c.country=s.country
    
--2008年中 ,天天有多少訂單
select orderdate,count(*)
from sales.orders
where orderdate between '20080101' and '20081231'
group by orderdate

select orderdate,count(*) over (partition order by orderdate)
from sales.orders
where orderdate between '20080101' and '20081231'

--建立一個表,向表裏寫入400條數據
create table nums
(
n int
)
declare @i int
set @i=1
while @i<400
 begin
set @i=@i+1
insert into values(@i)
end

--製做一個連續的日期

select dateadd(day,n,'20071231')
from nums

--與訂單表作一個鏈接
select dateadd(day,nums.n,'20071231') noorderdate
from nums left outer join salas.orders
     on dateadd(day,nums.n,'20071231')=sales.orders.orderdate
where sales.orders.orderid is null
order by noorderdate


--子查詢 
select lastname
where birthdate=(select max(birthdate) from hr.employees)

--獨立子查詢 沒有用到外部的子查詢叫獨立子查詢


--相關子查詢  解釋: 子查詢查詢出現了子查詢之外的查詢叫作相關子查詢
select custid,contactname,
(
select count(*)
from Sales.Orders 
where Sales.Orders.custid=Sales.Customerscustid
) as ordercount
from Sales.Customers

--還有一些複雜的狀況考慮
--多值子查詢   這裏用 exists 也可 是否存在
select distinct country
from Sales.Customers
where country not in
( 
select distinct country
from Production.Suppliers
)
--使用相關子查詢
select distinct country
from Sales.Customers c
where 
not exists
(
select country from Production.Suppliers s
 where s.country=c.country
 )


--高級子查詢

--查詢一個數字的上一個數和下個數   使用相關子查詢
select orderid,
  (
    select max(orderid)
    from Sales.orders innerT
    where innerT.orderid < outerT.orderid
  ) as prevOrder,
  (
  select min(orderid)
  from Sales.orders innerT
  where innerT.orderid> outerT.orderid
  ) as nextOrder
  from Sales.Order outerT


select e.empid,fistname,lastname
from Sales.Orders o right outer join Hr.Employees e
 on o.empid=e.empid and o.orderdate>='20080501'
 where o.orderid is null

--客戶表中出現過,僱員表中沒有出現過的國家
select distinct country
from Sales.Customers
where country not in (
 select country
  from hr.employees
)
--考慮用鏈接
select c.country
from Sales.Cutomers c left outer join Hr.Employees e
   on c.country =e.country 
   where c.country is null



--派生表 其實就是特殊的子查詢
--用在from 以後的子查詢
--特殊之處
-- 1.必須起別名,派生表必須起別名, 表達式必須起別名
select *
from (
   select custid,count(*) over(partition by country) as num
   from Sales.Customers
   where country='USA'
)  t 
--或者在外面起別名 t 的後面(custid,num)

--表表達式
--公用表表達式CTE 跟派生表很類似

--派生表實現
select  *
from 
(
  select companyname,country
  from Sales.Customers
  where country ='USA'
) t

--使用CTE
--先定義子查詢,命名
with usa_customers
as
(
 select companyname,country
 from Sales.Customers
  where country='USA'
)
select * from usa_customers

with usa_customers
as
(
select companyname as 公司名,country 國家
from Sales.Customers
where country='USA'
)
select * from usa_customers

--在CTE 使用參數
declare @country nvarchar(30);
set @country='USA';
with usa_customers(公司名,國家)
as
(
select companyname,country
from Sales.Customers
where country=@country
)
select * from usa_customers;

select year(orderdate),custid,count(*) orderdate
from Sales.Orders
group by year(orderdate),custid
having count(*)>10

select year(orderdate),custid
from Sales.Orders

select orderyear,custid,count(*)
from
(
 select year(orderdate) orderyear,custid
 from Sales.Orders
) as t1
group by orderyear,custid

select orderyear,custid,orderdate
from
(
 select orderyear,custid,count(*) as ordercount
 from
 (
 select year(orderdate) orderyear,custid
 from Sales.Orders
 ) as t1
 group by orderyear,custid
) as t2
where ordercount>10


--使用CTE
with withyearorders (orderyear,custid)
as
(
select year(orderdate),custid
from Sales.Orders
),
yearorders
as
(
 select orderyear,custid,count(*) as ordercount
 from withyearorders
 group by orderyear,custid
),
yearOrder10
as
(
 select orderyear,custid,ordercount
 from yearoders
 where ordercount>10
)
select * from yearOrder10

--派生表查詢
select t1.orderyear,t2.orderyear,t1.custcount-t2.custcount
from 
)
select year(orderdate) as orderyear,count(distinct custid) countcount
from Sales.Orders
group by year(orderdate)
) as t1
left outher join 
)
select year(orderdate) as orderyear,count(distinct custid) countcount
from Sales.Orders
group by year(orderdate)
) as t2
on t1.orderyear=t2.orderyear+1

--多個CTE 複用
with yearcust
as
(
 select year(orderdate) as orderyear,count(distinct custid) countcount
from Sales.Orders
group by year(orderdate)
)
select curr.orderyear,curr.custcount,prev.oderyear,prev.custcount
 curr.custcount-prev.custcount
from  yearcust as curr left outer join yearcust prev
 on curr.orderyear=prev.orderyear+1
 
 
 --自鏈接,鏈接兩遍的表實際上是同一張表,必定要起別名
 select e.empid,e.lastname,e.mgrid,e.empid,m.lastname
 from Hr.Employees e inner join Hr.Employees m
 on e.mgrid=e.empid
 
 
 --查詢員工的下屬 遞歸
 with emplist
 as
 (
  -- 起點 ,僅僅執行一次
  select empid,lastname,mgrid
  from Hr.Employees
  where mgrid=2
  union all   --合併
  --可能屢次執行,直到查詢結果爲空
  select e.empid,e.lastname,e.mgrid
  from Hr.Employees e inner join emplist m
  on e.mgrid=m.empid
 ) 
 select * from emplist
 option (maxrecursion 6);  --限制遞歸次數
 
 
 --View 視圖
 --把查詢保存在數據庫中,起名字,視圖
 create view usacustomers
 as
 select companyname,country
 from Sales.Customers
 where country='USA'
 
 go  --前面是單獨的,後面再執行
 
 create view myOrderValues
 as
 select o.oderid,custid,empid,shipperid,orderdate,
    sum(d.qty * d.unitprice) as    val
 from Sales.Orders o inner  join Sales.OrderDatails d
  on o.orderid=d.orderid
  group by o.orderid,custid,empid,shipperid,orderdate
  
--刪除視圖
drop view dbo.usacustomers

create view CustOrders
as
select o.custid,datediff(month,datediff(month,0,o.orderdate),0) as ordermonth,
sum(od.qty) as qty
from Sales.Orders as o inner join
Sales.OrderDetails as od on od.orderid=o.orderid
group by o.custid,datediff(month,datediff(month,0,o.orderdate),0)


select empid,max(orderdate) as maxorderdate
from Sales.Orders
group by empid

select o.empid,o.orderdate,o.orderid,o.custid
from
(
select empid,max(orderdate) as maxorderdate
from Sales.Orders
group by empid
) t
inner join Sales.Order o
on o.orderdate=t.maxorderdate and o.empid=t.empid 


with empmaxorder
as
(
select empid,max(orderdate) as maxorderdate
from Sales.Orders
group by empid 
)
select o.empid,o.orderdate,o.orderid,o.custid
from Sales.Orders o inner join empmaxorder em
on o.empid=em.empid and o.oderdate=em.maxorderdate;

select orderid,orderdate,custid,empid
 row_number() over( order by orderdate,orderid) as rownumber
 from Sales.Orders
 
 with numorders
 as
 (
 select orderid,orderdate,custid,empid
 row_number() over(order by orderdate,orderid) as rownum
 from Sales.Orders
 )
 select orderid,orderdate,custid,empid,rownum
 from numorders
 where rownum between 11 and 20
 
 --遞歸CTE
 with mangers
 as
 (
    --入口點
    select empid,mgrid,firstname,lastname
    from Hr.Employees
    where empid=9
    union all
    --遞歸查詢
    select e.empid,e.mgrid,e.firsname,lastname
    from mangers m inner join Hr.Employees e
    on m.mgrid = e.empid
 )
 select empid,mgrid,firsname,lastname
 from mangers
 
 go
 
 create view Sales.VEmpOrders
 as
 select empidi,year(orderdate) as orderyear,sum(qty) as qty
 from Sales.Orders o inner join Sales.orderdateils od
 on o.orderid=od.orderid
 group by empid,year(orderdate)
 
 
 --連續聚合
 
 select empid,orderyear,qty
 (
 select sum(qty)
 from Sales.VempOrders innerT
 where innerT.empid=outerT.empid 
        and innerT.orderyear<=outerT.orderyar
 ) as runqty
 from Sales.VempOrders outerT
 order by empid,orderyear
 
 
 with  vorders
 as
 (
 select empidi,year(orderdate) as orderyear,sum(qty) as qty
 from Sales.Orders o inner join Sales.orderdateils od
 on o.orderid=od.orderid
 group by empid,year(orderdate)
 )
  select empid,orderyear,qty
 (
 select sum(qty)
 from vorders innerT
 where innerT.empid=outerT.empid 
        and innerT.orderyear<=outerT.orderyar
 ) as runqty
 from vorders outerT
 order by empid,orderyear
 
 go
 
 --定義一個表函數
 create function production.topProducts
 (
 @supid  int,
 @num int 
 )
 returns table 
 as
  return 
  select top(@num) *
  from Production.Products
  where supplierid=@supid
  order by unitprice desc
 
 --調用 表函數
 select *
  from  production.topProducts(5,2)
 
 
 
 --交叉鏈接
 select s.supperlierid,companyname,
 productid,productname,unitprice
 from Production.Suppliers s
 cross apply production.topProducts(s.supplierid,2)
 
 
 --透視,逆透視及分組集合   表的轉置
 
 --分組查詢
 select empid ,custid,sum(qty) sumqty
 from dbo.orders
 group by empid,custid
 
 --對僱員進行分組
select empid,sum(qty)
from dbo.orders
group by empid

--增長顧客的列 1 號顧客  使用相關子查詢
select empid,
(
 select sum(qty)
 from dbo.orders innerT
 where custid=1 and innerT empid=outerT empid
) as A,
(
select sum(qty)
 from dbo.orders innerT
 where custid=2 and innerT empid=outerT empid
 ) as B,
 (
  select sum(qty)
  from dbo.orders innerT
  where custid=3 and innerT empid=outerT.empid
  ) as C
  from dbo.orders outerT
  group by empid
  

select empid,
        sum(case when custid=1 then qty end) as A,
        sum(case when custid=2 then qty end) as B,
        sum(case when custid=3 then qty end) as C,
        sum(qty)
from dbo.orders
group by empid



使用 pivot 語法實現透視
select empid,count(*)
        count(case when year(orderdate)=2006 then orderdate end)
        as nums2006,
        count(case when year(orderdate)=2007 then orderdate end)
        as nums2007,
        (
        select count(*)
        from Sales.Orders innerT
        where innerT.empid=outerT.empid and year(orderdate)=2008
        ),
        sum(qty)
from sales.orders outerT
group by empid


select empid,[1],[2],[3]
from (
    --僅僅返回透視中用到的列
    select empid,qty,custid
    from dbo.orders
)  t   --分組是隱含的,對錶中除掉聚合和條件的列進行聚合
 pivot(
   sum(qty)            --聚合函數
   from custid in([1],[2],[3]) --準備作列名
 ) as p;
   

select empid,[2006],[2007],[2008]
from 
    (
    select empid,year(orderdae) orderyear,orderid
    from Sales.Orders
    ) as t
    piovt
      (
        count(orderid)
        from orderyear in([2006],[2007],[2008])
      ) as p
order by empid;


---計算每一個客戶每一年的支出金額
select custid, year(orderdate) as orderyear,sum(od.qty *od.unitprice) totalprice
from Salas.Orders o inner join Sales.ORderDatails od
group by custid,year(orderdate)
      

select custid,[2006],[2007],[2008]
from (
 select custid, year(orderdate) as orderyear,sum(od.qty *od.unitprice) totalprice
from Salas.Orders o inner join Sales.ORderDatails od
group by custid,year(orderdate)  
) t
pivot(
sum(totalprice)
for orderyear in([2006],[2007],[2008])
) p;


if DB_ID('school') is not null
 begin 
   use master;
  drop database school;
  end

create database school;

use school;

--schema , 默認 dbo
create schema student;
go

if object_id('student.Students','U') is not null
    drop table student.Students;
--考慮定義一張表
create table student.Students
(
studid int identity(1,1) not null,-- 非空約束
studentname nvarchar(20) not null,
classid int, 
--外鍵約束
constraint fk_classid foreign key(classId) 
references classs(id),
--性別
gender nvarchar(1),
--檢查約束
constraint ck_gender  check(gender in('','')),
 --惟一約束
constraint uq_name unique(studentname),
--主鍵約束,主鍵中能存在一組,可是惟一約束能夠由多組
constraint pk_id primary key(studid)
);
go
--插入數據  所有字段都賦值
insert into student.Students values(1,'tom');



--一般使用指定字段名的方式
insert into student.Students(studentname,studid)
values('alice',2)

--另一種寫法
insert student.Students(studid,studentname)
select '','' union,
select '','' union,
select '','' union,
select '','' union

--聯合這兩個表
select bookName from myrank
union  --去重複
select bookName from mybook;

--聯合這兩個表  顯示重複數據
select bookName from myrank
union all  --不去重複
select bookName from mybook;

insert into select語句則是從一個表中複製數據而後插入到另外一個已存在的表中,目標表中原有的行不會受到任何影響。

insert into myrank(userId) select userID from mybook

select * from student.Students;


--事務和併發

--隱式事務

--顯示事務,明確指出事務的起止邊界
begin transaction
delete from Sales.Shippers where shipperid=4
delete from Sales.Shippers where shipperid=5
--回滾
rollback 
--提交
commit

--事務必須有四個屬性
--原子性(Atomicity),一致性(Consistency),隔離性(Isolation)
--持久性(Durabillity) 這四個屬性的首字母能夠縮寫成ACID


--設置隔離級別能夠讀取未提交的數據 
set transaction isolation level read uncommitted


--其實就是加鎖,加上共享鎖
--普通狀況下,查詢的時候,系統加上共享鎖,查詢結束,
--鎖撤銷
--咱們如今,但願在查詢結束以後,共享鎖依然存在,保證數據不被修改

set transaction isolation level repeatable read;




--可編程對象
--定義變量
declare @i int
set @i=10
print @i;

declare @i varchar(20)
set @i='Hello,world';
print @i;

declare @i nchar(20) --固定長度
set @i='Hello';      --已經佔用了全部的空間
set @i=@2+',world';
print @i;

--還可使用select 對變量賦值
select @i=99;
print @i;

--當前時間
declare @now datetime
set @now=getdate();
print @now;


--查詢顧客的數量,保存到變量中使用
declare @customerCount int;
select @customerCount= count(*)   --賦值語句
from Sales.Customers;
print @customerCount;

--選擇結構
--條件 
--取得當前時間的分鐘部分
declare @mi int;
set @mi=datepart(minute,getdate());
if @mi>10
  begin 
    print '下課'
  end
else 
  begin
    print '繼續學習'
  end
  
break



--遊標

select companyname
from sales.customers

--簡單變量,標量
declare @name nvarchar(100)
select @name=companyname
from sales.customers;
print @name;

--使用遊標   是把數據逐條查詢出來
--1. 聲明遊標,基於查詢  
declare c cursor
    for
    select custid, companyname
    from sales.customer
    
declare @name nvarchar(100);
declare @id int;
--2.在使用以前,必須打開遊標
open c;
--3. 從遊標中讀取查詢數據,每次能夠讀取一條記錄
fetch next from c into @id,@name
--4. 注意fetch 並不必定獲取實際的數據
while @@fetch_status=0   --成功獲取了數據
begin 
 print @name;
  -- 燃火,試探獲取下一條數據
  fetch next from c into @id,@name;
end
--5. 遊標使用完畢,必定要關閉
close c;
--6.釋放遊標
deallocate c;


--局部臨時表  名字前面有一個#表示局部臨時表
create table #temptable
(
  num  int
)
--使用與表相同
insert into #temptable (num) values(1),(1),(2),(3),(5);

--全局臨時表
--使用方式名字前面有兩個##
create table ##globaltable
(
 name nvarchar(20)
)
--表變量
declare @table table
(
 num int
)
insert into @table (num) values(1),(1),(2),(3),(5)
select * from @table

--靜態SQL 

--動態SQL
declare @sql nvarchar(200)
set @sql='select companyname from seles.customers'
print @sql;
--將一個字符串當作一個SQL 語句動態執行
exec(@sql);


--sql 注入攻擊

declare @sql nvarchar(200);
set @sql='select custid,companyname from seles.customers where
 custid=@id';
 
 --用戶輸入查詢的編號
 declare @input int;
 set @input=23;
 --原則,用戶的輸入是邪惡的
 --set @input='abc';
 --set @input='0 or 1=1';
 --set @input='0; select * from sales.customers';
 print @sql;
 
 --將一個字符串當作一個SQL 語句動態執行
 exec sp_executesql 
        @stmt=@sql;   --表示要執行的SQL語句
        @params= N'@id as int';  --聲明命令中須要的參數
        @id=@input;  --後面依次提供參數
 go
 

--調整價格寫成一段程序,保存到數據庫中
--存儲過程
create procedure ModifyPrice
(
  @num  money 
)
as 
update production products
        set unitprice=unitprice=@num;

--存儲過程保存在數據庫中
exec dbo.ModifyPrice @num=10;

--參數問題
--1.傳入參數
--  傳統的參數,默認的參數就是傳入參數
--2.傳出參數
--  out,ref 參數

--查詢顧客的數量
--與方法不一樣,存儲過程沒有一般意義上的返回類型和返回值
create procedure GetCustomerCount
(
@count int output  --參數有output 傳出參數
)
as 
declare @num int;
select @num=count(*) from sales.customers;
print @num;

--使用帶有傳出參數的存儲過程
--必然使用變量來保存傳出的結果
declare @mycount int;
--前面是參數定義的傳出參數名稱
--後面是 咱們定義的用來保存傳出結果的變量
exec dbo.GetCustomerCount @count=@mycount output;
print @mycount


create procedure createuser
(
 @username nvarchar(100)
)
 as 
    declare @namelen int;
    set @namelen=len(@username)
    if @namelen>=5
       return 0
    else 
       return 1;
       
--調用 獲取返回結果是否成功
declare @returnValue int;
exec @returnValue=createuser @username='23423432'
print @returnValue

--建立函數
create function getminute
(
 @datevalue datetime   --傳入參數
)
--函數能夠直接返回一個值
returns int
as
 --函數體
begin
   declare @mi int
   set @mi=datepart(minute,@datevalue);
   return @mi;
end

--調用
select dbo.getminute(getdate())

--觸發器
--建立一個日誌表,記錄對貨運的操做
create table shipper_log
(
 logid int identity(1,1) primary key,
 opdate datetime default getdate(),
 opuse nvarchar(20),
 op nvarchar(20),
 shipname nvarchar(50),
 shipphone nvarchar(20)
 )
 --建立一個審覈貨運公司的觸發器
 create trigger tg_ship 
 --觸發器沒有參數,因爲經過數據庫系統調用
 on Sales.Shippers after insert,delete,update
 as
   insert into shipper_log(opuse,op,shipname,shipphone)
   select user_name(),'插入',companyname,phone
   from inserted;
 
--標識問題
--得到系統提供的標識值,獲取整個系統系統範圍內
select @@identity

--應該使用這個,獲取當前做用域中最新生成的標識值
select scope_identity();
 
 
select datepart(day,'20161228','20140624')

--多表查詢
with 
a as (select '60000' cw1, 200 cw2, '2010-12-31' cw3),
b as (select '60000' CW1, '銀行' CW2),
c as (select '銀行' cw1, 121 cw2, '2010-12-31' CW3)
select a.cw1 '公司',a.cw2 '財務',b.CW2 '行業',c.cw2 '平均值' 
from a
inner join b on a.cw1=b.CW1
inner join c on b.CW2=c.cw1
where a.cw2>c.cw2

--參照更新格式
update a
set a.字段=b.字段
from a join b on a.xx=b.xx
where

--查詢表中重複的數據
select 字段,sun(1) as c
fromgroup by 字段
having sum(1)>1

--高效分頁
declare @pagesize int,@pageindex int
set @pagesize=20;
set @pageindex=1;
with temp
as
(
select ROW_NUMBER() over(order by id) [row_number],* from dbo.t_user
)
select * from temp where temp.row_number between @pagesize*(@pageindex-1)+1 and @pagesize*@pageindex

--將mybook表的數據複製到mybookcopy表中,mybookcopy表無需咱們建立,執行這條語句後會自動建立mybookcopy表
select * into mybookcopy from mybook;
--複製多個表的列到新表中
select mybook.bookName,myuser.userName into newtable from mybook join myuser on mybook.userID=myuser.userId

select * from A a,B b where a.id_a=b.id_b

DECLARE @pageIndex INT,@pageSize INT
SET @pageIndex=1
SET @pageSize=10
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY [TelePhone]) AS [ROW_NUMBER],[TelePhone] FROM TB_NUSERS
) AS T WHERE [ROW_NUMBER] BETWEEN @pageSize*(@pageIndex-1)+1 AND @pageIndex*@pageSize

 

--刪除重複記錄
delete [dbo].[T_moblie_info_bak1] where UniqueId not in(
select max(UniqueId) from [dbo].[T_moblie_info_bak1] group by moblie)

--刪除相同數據
delete [dbo].[T_moblie_info_bak] where UniqueId not in(
select UniqueId from [dbo].[T_moblie_info_bak] m where UniqueId in(
select top 1 UniqueId from [dbo].[T_moblie_info_bak] t where m.moblie=t.moblie))
相關文章
相關標籤/搜索