码迷,mamicode.com
首页 > 数据库 > 详细

T-SQL基本语法

时间:2016-03-29 16:15:51      阅读:303      评论:0      收藏:0      [点我收藏+]

标签:

   1 --查询
   2 select DB_ID(B2C) 
   3 
   4 --检查数据库是否存在
   5 if DB_ID(B2C) is not null
   6 
   7 --使用数据库
   8 use B2C 
   9 
  10 --单引号表示字符串,双引号则不是 U 表示用户表
  11 select OBJECT_ID(UserName,U)  
  12 --主键约束Primary key 
  13 --唯一约束Unique
  14 --外键约束foreign key () references 
  15 --检查约束Check
  16 --非空约束
  17 
  18 --Select 语句的元素
  19 --From
  20 --Where
  21 --Group by
  22 --Having
  23 --Select
  24 --Order by
  25 
  26 --表达式
  27 select  orderdate,year(orderdate) as 订单年份
  28 from Orders;
  29 --选择
  30 select orderdate,year(orderdate) as 订单年份
  31 from Orders
  32 where year(orderdate)=2006
  33 
  34 --查询同一年出生的员工人数
  35 select YEAR(birthdate),COUNT(*)
  36 from Employee
  37 group by YEAR(birthdate)
  38 
  39 --百分比
  40 select top (20) percent lastname,firstname
  41 from hr.employees
  42 
  43 --开窗函数 over 
  44 select lastname,firstname,count(*) over ()
  45 from hr.employees
  46 
  47 --带有总价的订单
  48 --partition by  相当于做一个相对的选择,选出等于的值
  49 select lastname,firstname,val
  50 ,sum(val) over( partition by custid) as 顾客总价
  51 ,sum(val) over() as 总价
  52 from Sales.OrderValues
  53 
  54 --排名函数
  55 --row_number 行号  必须与 over 配合
  56 --rank       排名
  57 --dense_rank 密集排名
  58 --ntile      分组
  59 select row_number() over( order by lastname ),lastname,firstname
  60        rank()       over( order by country) as 排名,
  61        dense_rank() over( order by country) as 密集排名,
  62        ntile(5)     over( order by country) as 分组,
  63 from hr.employees
  64 
  65 
  66 --排名结合部分
  67 select row_number() over( order by country)
  68        row_number() over( partition by country order by country),
  69        country,lastname,firstname
  70       from hr.employees
  71 
  72 --between and 
  73 select *
  74 from OrderValues
  75 where val between 1000 and 200
  76 
  77 --in 枚举值
  78 select *
  79 from OrderValues
  80 where custid in (1,2,8)
  81 
  82 
  83 --like 字符串匹配  % 任意多个任意字符  _任意一个任意字符
  84 
  85 
  86 
  87 --简单表达式
  88 select lastname,region,
  89  case  region          -switch 
  90        when WA then 华盛顿   --case 
  91        else 其他特区
  92   end
  93 from employees
  94 
  95 --搜索表达式
  96 select lastname,region,
  97 case 
  98      when region=WA then 华盛顿特区
  99      when region is null then 位置地区
 100      else 其它地区
 101 end
 102 from employees;
 103 
 104 
 105 --定义变量
 106 declare @s char(10),
 107 --赋值之后,实际上已经填满了10个字符
 108 set @s=hello
 109 print @s
 110 set @s = @s+world
 111 print @s
 112 
 113 --注意:在SQL 中,下标从1开始
 114 select productname,substring(productname,9,10)
 115 from production.Products
 116 
 117 --left 表示左边
 118 select productname, left(productname,8)
 119 from production.Products
 120 
 121 --right 表示取右边的部分
 122 select productname,right(productname,8)
 123 from production.Products
 124 
 125 --模版在前,源字符串在后,空格出现在名字中的位置,从1开始
 126 select productname,charindex(‘‘,productname)
 127 from production.Products
 128 
 129 --将产品名称中的product 替换为产品名
 130 select productname,replace(productname,Product,产品名)
 131 from production.Products
 132 
 133 --stuff 替换
 134 select productname,stuff(productname,8,1, : )
 135 from production.Products
 136 
 137 --转换大写 和 小写
 138 select productname,upper(productname),lower(productname)
 139 from production.Products
 140 
 141 --去空格
 142 select  datalength(rtrim(string))
 143 select ltrim(rtrim(string))
 144 
 145 
 146 --字符串方式表示日期
 147 select orderid,orderdate 
 148 from Sales.orders
 149 where orderdate > 20080301
 150 
 151 --cast 转换 datetime   这个和上面一个是等价的
 152 select orderid,orderdate
 153 from Sales.orders
 154 where orderdate > cast (20080301 as datetime)
 155 
 156 -- datepart 取日期中的一部分
 157 select getdate()
 158 
 159 --年,月,日,小时,分钟,秒
 160 select datepart(year,getdate()),
 161        datepart(month,getdate()),
 162        datepart(day,getdate()),
 163        datepart(hour,getdate()),
 164        datepart(minute,getdate()),
 165        datepart(second,getdate()
 166        
 167 --特殊
 168 select datepart(dayofyear,getdate()),-- 从年初到现在的天数
 169        datepart(weekday,getdate()),--星期几,从星期天开始为1
 170        datepart(week,getdate()) --今年的第几周
 171 
 172 select year(getdate()),month(getdate()),day(getdate()
 173 
 174 --日期加和减  日期加法 单位
 175 select getdate(),dateadd(month,2,getdate()) -- 加两个月
 176        dateadd(year,3,getdate()),
 177        dateadd(minute,30,getdate())
 178        
 179 --日期减法 单位
 180 select datediff(year,19491001,getdate())
 181 
 182 --计算今年多少岁
 183 select datediff(year,19800101,getdate())
 184 
 185 --练习1
 186 select *
 187 from Sales.Orders
 188 where year(orderdate)=2007 and month(orderdate)=7
 189 
 190 select *
 191 from Sales.Orders
 192 where datepart(year,orderdate)=2007 and
 193       datepart(month,orderdate)=6
 194 --还可以 ‘200706‘
 195 --将日期转换成字符串
 196 select *
 197 from Sales.Orders
 198 where left(convert(nvarchar,(orderdate),112),6)=200706
 199 
 200 select getdate(),convert(nvarchar,getdate(),112),
 201        left(convert(nvarchar,getdate(),112),6)
 202        
 203 select convert(int,99)+100
 204 select cast(99 as int)+100
 205 
 206 select orderid,sum(unitprice * qty)
 207 from Sales.Orderdatails
 208 group by orderid
 209 having sum(unitprice *qty) >10000
 210 order by sum(unitprice * qty) desc
 211 
 212 --3-1交叉连接和内连接
 213 --连接查询  cross 翻译十字   所以的都做了一次匹配
 214 select empid,shipperid
 215 from Hr.employees cross join Sales.Shippers
 216 
 217 --内连接  必须符合特定条件的组合
 218 select c.categoryid,productid,p.productname,c.categoryname
 219 from production.Categories c inner join production.products p
 220 on c.categoryid=p.categoryid
 221 
 222 --查询每个顾客的名称,已经下过多少张订单
 223 select distinct c.custid,contactname,orderid,
 224        count(*) over(partition by o.custid)
 225        from Sales.Customers c inner join Sales.Orders o
 226        on c.custid=o.custid
 227        
 228 --插入10 条记录
 229 insert into digits (digit)
 230 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
 231 
 232 --生成数字
 233 select d1.digit,d2.digit, d3.digit* 10 + d2.digit*10 +d1.digit
 234 from digits di cross join digits d2
 235   cross join digits d3
 236 
 237 --实现1-1000
 238 select row_number() over(order by d1.digit) as digit
 239 from digits d1 cross join digits d2
 240      cross join digits d3
 241      order by digit
 242 
 243 --查询每张订单多少钱
 244 select distinct o.orderid,orderdate,
 245      sum(qty * unitprice) over(partition by o.orderid)
 246 from Sales.Orders o inner join Sales.OrderDatails d
 247 on o.orderid=d.orderid
 248 
 249 --左外连接
 250 select count(*)
 251 from Sales.Customers c left outer join Sales.Order o
 252 on c.sutid =o.custid
 253 
 254 --右外连接
 255 select count(*)
 256 from Sales.Customers c right outer join Sales.Order o
 257 on c.sutid =o.custid
 258 
 259 --组函数不包含 Null
 260 select  distinct c.contactname,
 261 count(o.orderid) over(partition by c.custid)  ordercount
 262 from Sales.Customers c left outer join Sales.Orders o
 263 on c.custid=o.custid
 264 order by ordercount
 265 
 266 --查询一下所有的雇员都处理过订单
 267  select e.empid,count(o.orderid),lastname
 268  from hr.employee e left outer join sales.orders o
 269       on e.empid=o.empid
 270 group by e.empid,lastname
 271 having count(o.orderid)=0
 272 
 273 
 274 --将员工表和订单表做一个外连接
 275 select e.empid,e.lastname
 276 from left outer join sales.orders o
 277 where o.orderis is null
 278 
 279 --查询有顾客但是没有供应商的国家
 280 select distinct c.country as 客户国家,s.country as 供应商国家
 281 from Sales.Customers c left outer join Production.Suppliers s
 282      on c.country=s.country
 283 where c.country is null
 284 
 285 --全外连接,查询所有的国家,有无供应商,有无顾客
 286 select distinct c.country as 客户国家,s.country as 供应商国家
 287 from Sales.Customers c full outer join Production.Suppliers s
 288     on c.country=s.country
 289     
 290 --2008年中 ,每天有多少订单
 291 select orderdate,count(*)
 292 from sales.orders
 293 where orderdate between 20080101 and 20081231
 294 group by orderdate
 295 
 296 select orderdate,count(*) over (partition order by orderdate)
 297 from sales.orders
 298 where orderdate between 20080101 and 20081231
 299 
 300 --创建一个表,向表里写入400条数据
 301 create table nums
 302 (
 303 n int
 304 )
 305 declare @i int
 306 set @i=1
 307 while @i<400
 308  begin
 309 set @i=@i+1
 310 insert into values(@i)
 311 end
 312 
 313 --制作一个连续的日期
 314 
 315 select dateadd(day,n,20071231)
 316 from nums
 317 
 318 --与订单表做一个连接
 319 select dateadd(day,nums.n,20071231) noorderdate
 320 from nums left outer join salas.orders
 321      on dateadd(day,nums.n,20071231)=sales.orders.orderdate
 322 where sales.orders.orderid is null
 323 order by noorderdate
 324 
 325 
 326 --子查询 
 327 select lastname
 328 where birthdate=(select max(birthdate) from hr.employees)
 329 
 330 --独立子查询 没有用到外部的子查询叫独立子查询
 331 
 332 
 333 --相关子查询  解释: 子查询查询出现了子查询以外的查询叫做相关子查询
 334 select custid,contactname,
 335 (
 336 select count(*)
 337 from Sales.Orders 
 338 where Sales.Orders.custid=Sales.Customerscustid
 339 ) as ordercount
 340 from Sales.Customers
 341 
 342 --还有一些复杂的情况考虑
 343 --多值子查询   这里用 exists 也可 是否存在
 344 select distinct country
 345 from Sales.Customers
 346 where country not in
 347 ( 
 348 select distinct country
 349 from Production.Suppliers
 350 )
 351 --使用相关子查询
 352 select distinct country
 353 from Sales.Customers c
 354 where 
 355 not exists
 356 (
 357 select country from Production.Suppliers s
 358  where s.country=c.country
 359  )
 360 
 361 
 362 --高级子查询
 363 
 364 --查询一个数字的上一个数和下个数   使用相关子查询
 365 select orderid,
 366   (
 367     select max(orderid)
 368     from Sales.orders innerT
 369     where innerT.orderid < outerT.orderid
 370   ) as prevOrder,
 371   (
 372   select min(orderid)
 373   from Sales.orders innerT
 374   where innerT.orderid> outerT.orderid
 375   ) as nextOrder
 376   from Sales.Order outerT
 377 
 378 
 379 select e.empid,fistname,lastname
 380 from Sales.Orders o right outer join Hr.Employees e
 381  on o.empid=e.empid and o.orderdate>=20080501
 382  where o.orderid is null
 383 
 384 --客户表中出现过,雇员表中没有出现过的国家
 385 select distinct country
 386 from Sales.Customers
 387 where country not in (
 388  select country
 389   from hr.employees
 390 )
 391 --考虑用连接
 392 select c.country
 393 from Sales.Cutomers c left outer join Hr.Employees e
 394    on c.country =e.country 
 395    where c.country is null
 396 
 397 
 398 
 399 --派生表 其实就是特殊的子查询
 400 --用在from 之后的子查询
 401 --特殊之处
 402 -- 1.必须起别名,派生表必须起别名, 表达式必须起别名
 403 select *
 404 from (
 405    select custid,count(*) over(partition by country) as num
 406    from Sales.Customers
 407    where country=USA
 408 )  t 
 409 --或者在外面起别名 t 的后面(custid,num)
 410 
 411 --表表达式
 412 --公用表表达式CTE 跟派生表很相似
 413 
 414 --派生表实现
 415 select  *
 416 from 
 417 (
 418   select companyname,country
 419   from Sales.Customers
 420   where country =USA
 421 ) t
 422 
 423 --使用CTE
 424 --先定义子查询,命名
 425 with usa_customers
 426 as
 427 (
 428  select companyname,country
 429  from Sales.Customers
 430   where country=USA
 431 )
 432 select * from usa_customers
 433 
 434 with usa_customers
 435 as
 436 (
 437 select companyname as 公司名,country 国家
 438 from Sales.Customers
 439 where country=USA
 440 )
 441 select * from usa_customers
 442 
 443 --在CTE 使用参数
 444 declare @country nvarchar(30);
 445 set @country=USA;
 446 with usa_customers(公司名,国家)
 447 as
 448 (
 449 select companyname,country
 450 from Sales.Customers
 451 where country=@country
 452 )
 453 select * from usa_customers;
 454 
 455 select year(orderdate),custid,count(*) orderdate
 456 from Sales.Orders
 457 group by year(orderdate),custid
 458 having count(*)>10
 459 
 460 select year(orderdate),custid
 461 from Sales.Orders
 462 
 463 select orderyear,custid,count(*)
 464 from
 465 (
 466  select year(orderdate) orderyear,custid
 467  from Sales.Orders
 468 ) as t1
 469 group by orderyear,custid
 470 
 471 select orderyear,custid,orderdate
 472 from
 473 (
 474  select orderyear,custid,count(*) as ordercount
 475  from
 476  (
 477  select year(orderdate) orderyear,custid
 478  from Sales.Orders
 479  ) as t1
 480  group by orderyear,custid
 481 ) as t2
 482 where ordercount>10
 483 
 484 
 485 --使用CTE
 486 with withyearorders (orderyear,custid)
 487 as
 488 (
 489 select year(orderdate),custid
 490 from Sales.Orders
 491 ),
 492 yearorders
 493 as
 494 (
 495  select orderyear,custid,count(*) as ordercount
 496  from withyearorders
 497  group by orderyear,custid
 498 ),
 499 yearOrder10
 500 as
 501 (
 502  select orderyear,custid,ordercount
 503  from yearoders
 504  where ordercount>10
 505 )
 506 select * from yearOrder10
 507 
 508 --派生表查询
 509 select t1.orderyear,t2.orderyear,t1.custcount-t2.custcount
 510 from 
 511 )
 512 select year(orderdate) as orderyear,count(distinct custid) countcount
 513 from Sales.Orders
 514 group by year(orderdate)
 515 ) as t1
 516 left outher join 
 517 )
 518 select year(orderdate) as orderyear,count(distinct custid) countcount
 519 from Sales.Orders
 520 group by year(orderdate)
 521 ) as t2
 522 on t1.orderyear=t2.orderyear+1
 523 
 524 --多个CTE 复用
 525 with yearcust
 526 as
 527 (
 528  select year(orderdate) as orderyear,count(distinct custid) countcount
 529 from Sales.Orders
 530 group by year(orderdate)
 531 )
 532 select curr.orderyear,curr.custcount,prev.oderyear,prev.custcount
 533  curr.custcount-prev.custcount
 534 from  yearcust as curr left outer join yearcust prev
 535  on curr.orderyear=prev.orderyear+1
 536  
 537  
 538  --自连接,连接两遍的表其实是同一张表,一定要起别名
 539  select e.empid,e.lastname,e.mgrid,e.empid,m.lastname
 540  from Hr.Employees e inner join Hr.Employees m
 541  on e.mgrid=e.empid
 542  
 543  
 544  --查询员工的下属 递归
 545  with emplist
 546  as
 547  (
 548   -- 起点 ,仅仅执行一次
 549   select empid,lastname,mgrid
 550   from Hr.Employees
 551   where mgrid=2
 552   union all   --合并
 553   --可能多次执行,直到查询结果为空
 554   select e.empid,e.lastname,e.mgrid
 555   from Hr.Employees e inner join emplist m
 556   on e.mgrid=m.empid
 557  ) 
 558  select * from emplist
 559  option (maxrecursion 6);  --限制递归次数
 560  
 561  
 562  --View 视图
 563  --把查询保存在数据库中,起名字,视图
 564  create view usacustomers
 565  as
 566  select companyname,country
 567  from Sales.Customers
 568  where country=USA
 569  
 570  go  --前面是单独的,后面再执行
 571  
 572  create view myOrderValues
 573  as
 574  select o.oderid,custid,empid,shipperid,orderdate,
 575     sum(d.qty * d.unitprice) as    val
 576  from Sales.Orders o inner  join Sales.OrderDatails d
 577   on o.orderid=d.orderid
 578   group by o.orderid,custid,empid,shipperid,orderdate
 579   
 580 --删除视图
 581 drop view dbo.usacustomers
 582 
 583 create view CustOrders
 584 as
 585 select o.custid,datediff(month,datediff(month,0,o.orderdate),0) as ordermonth,
 586 sum(od.qty) as qty
 587 from Sales.Orders as o inner join
 588 Sales.OrderDetails as od on od.orderid=o.orderid
 589 group by o.custid,datediff(month,datediff(month,0,o.orderdate),0)
 590 
 591 
 592 select empid,max(orderdate) as maxorderdate
 593 from Sales.Orders
 594 group by empid
 595 
 596 select o.empid,o.orderdate,o.orderid,o.custid
 597 from
 598 (
 599 select empid,max(orderdate) as maxorderdate
 600 from Sales.Orders
 601 group by empid
 602 ) t
 603 inner join Sales.Order o
 604 on o.orderdate=t.maxorderdate and o.empid=t.empid 
 605 
 606 
 607 with empmaxorder
 608 as
 609 (
 610 select empid,max(orderdate) as maxorderdate
 611 from Sales.Orders
 612 group by empid 
 613 )
 614 select o.empid,o.orderdate,o.orderid,o.custid
 615 from Sales.Orders o inner join empmaxorder em
 616 on o.empid=em.empid and o.oderdate=em.maxorderdate;
 617 
 618 select orderid,orderdate,custid,empid
 619  row_number() over( order by orderdate,orderid) as rownumber
 620  from Sales.Orders
 621  
 622  with numorders
 623  as
 624  (
 625  select orderid,orderdate,custid,empid
 626  row_number() over(order by orderdate,orderid) as rownum
 627  from Sales.Orders
 628  )
 629  select orderid,orderdate,custid,empid,rownum
 630  from numorders
 631  where rownum between 11 and 20
 632  
 633  --递归CTE
 634  with mangers
 635  as
 636  (
 637     --入口点
 638     select empid,mgrid,firstname,lastname
 639     from Hr.Employees
 640     where empid=9
 641     union all
 642     --递归查询
 643     select e.empid,e.mgrid,e.firsname,lastname
 644     from mangers m inner join Hr.Employees e
 645     on m.mgrid = e.empid
 646  )
 647  select empid,mgrid,firsname,lastname
 648  from mangers
 649  
 650  go
 651  
 652  create view Sales.VEmpOrders
 653  as
 654  select empidi,year(orderdate) as orderyear,sum(qty) as qty
 655  from Sales.Orders o inner join Sales.orderdateils od
 656  on o.orderid=od.orderid
 657  group by empid,year(orderdate)
 658  
 659  
 660  --连续聚合
 661  
 662  select empid,orderyear,qty
 663  (
 664  select sum(qty)
 665  from Sales.VempOrders innerT
 666  where innerT.empid=outerT.empid 
 667         and innerT.orderyear<=outerT.orderyar
 668  ) as runqty
 669  from Sales.VempOrders outerT
 670  order by empid,orderyear
 671  
 672  
 673  with  vorders
 674  as
 675  (
 676  select empidi,year(orderdate) as orderyear,sum(qty) as qty
 677  from Sales.Orders o inner join Sales.orderdateils od
 678  on o.orderid=od.orderid
 679  group by empid,year(orderdate)
 680  )
 681   select empid,orderyear,qty
 682  (
 683  select sum(qty)
 684  from vorders innerT
 685  where innerT.empid=outerT.empid 
 686         and innerT.orderyear<=outerT.orderyar
 687  ) as runqty
 688  from vorders outerT
 689  order by empid,orderyear
 690  
 691  go
 692  
 693  --定义一个表函数
 694  create function production.topProducts
 695  (
 696  @supid  int,
 697  @num int 
 698  )
 699  returns table 
 700  as
 701   return 
 702   select top(@num) *
 703   from Production.Products
 704   where supplierid=@supid
 705   order by unitprice desc
 706  
 707  --调用 表函数
 708  select *
 709   from  production.topProducts(5,2)
 710  
 711  
 712  
 713  --交叉连接
 714  select s.supperlierid,companyname,
 715  productid,productname,unitprice
 716  from Production.Suppliers s
 717  cross apply production.topProducts(s.supplierid,2)
 718  
 719  
 720  --透视,逆透视及分组集合   表的转置
 721  
 722  --分组查询
 723  select empid ,custid,sum(qty) sumqty
 724  from dbo.orders
 725  group by empid,custid
 726  
 727  --对雇员进行分组
 728 select empid,sum(qty)
 729 from dbo.orders
 730 group by empid
 731 
 732 --增加顾客的列 1 号顾客  使用相关子查询
 733 select empid,
 734 (
 735  select sum(qty)
 736  from dbo.orders innerT
 737  where custid=1 and innerT empid=outerT empid
 738 ) as A,
 739 (
 740 select sum(qty)
 741  from dbo.orders innerT
 742  where custid=2 and innerT empid=outerT empid
 743  ) as B,
 744  (
 745   select sum(qty)
 746   from dbo.orders innerT
 747   where custid=3 and innerT empid=outerT.empid
 748   ) as C
 749   from dbo.orders outerT
 750   group by empid
 751   
 752 
 753 select empid,
 754         sum(case when custid=1 then qty end) as A,
 755         sum(case when custid=2 then qty end) as B,
 756         sum(case when custid=3 then qty end) as C,
 757         sum(qty)
 758 from dbo.orders
 759 group by empid
 760 
 761 
 762 
 763 使用 pivot 语法实现透视
 764 select empid,count(*)
 765         count(case when year(orderdate)=2006 then orderdate end)
 766         as nums2006,
 767         count(case when year(orderdate)=2007 then orderdate end)
 768         as nums2007,
 769         (
 770         select count(*)
 771         from Sales.Orders innerT
 772         where innerT.empid=outerT.empid and year(orderdate)=2008
 773         ),
 774         sum(qty)
 775 from sales.orders outerT
 776 group by empid
 777 
 778 
 779 select empid,[1],[2],[3]
 780 from (
 781     --仅仅返回透视中用到的列
 782     select empid,qty,custid
 783     from dbo.orders
 784 )  t   --分组是隐含的,对表中除掉聚合和条件的列进行聚合
 785  pivot(
 786    sum(qty)            --聚合函数
 787    from custid in([1],[2],[3]) --准备做列名
 788  ) as p;
 789    
 790 
 791 select empid,[2006],[2007],[2008]
 792 from 
 793     (
 794     select empid,year(orderdae) orderyear,orderid
 795     from Sales.Orders
 796     ) as t
 797     piovt
 798       (
 799         count(orderid)
 800         from orderyear in([2006],[2007],[2008])
 801       ) as p
 802 order by empid;
 803 
 804 
 805 ---计算每个客户每年的支出金额
 806 select custid, year(orderdate) as orderyear,sum(od.qty *od.unitprice) totalprice
 807 from Salas.Orders o inner join Sales.ORderDatails od
 808 group by custid,year(orderdate)
 809       
 810 
 811 select custid,[2006],[2007],[2008]
 812 from (
 813  select custid, year(orderdate) as orderyear,sum(od.qty *od.unitprice) totalprice
 814 from Salas.Orders o inner join Sales.ORderDatails od
 815 group by custid,year(orderdate)  
 816 ) t
 817 pivot(
 818 sum(totalprice)
 819 for orderyear in([2006],[2007],[2008])
 820 ) p;
 821 
 822 
 823 if DB_ID(school) is not null
 824  begin 
 825    use master;
 826   drop database school;
 827   end
 828 
 829 create database school;
 830 
 831 use school;
 832 
 833 --schema , 默认 dbo
 834 create schema student;
 835 go
 836 
 837 if object_id(student.Students,U) is not null
 838     drop table student.Students;
 839 --考虑定义一张表
 840 create table student.Students
 841 (
 842 studid int identity(1,1) not null,-- 非空约束
 843 studentname nvarchar(20) not null,
 844 classid int, 
 845 --外键约束
 846 constraint fk_classid foreign key(classId) 
 847 references classs(id),
 848 --性别
 849 gender nvarchar(1),
 850 --检查约束
 851 constraint ck_gender  check(gender in(,)),
 852  --唯一约束
 853 constraint uq_name unique(studentname),
 854 --主键约束,主键中能存在一组,但是唯一约束可以由多组
 855 constraint pk_id primary key(studid)
 856 );
 857 go
 858 --插入数据  全部字段都赋值
 859 insert into student.Students values(1,tom);
 860 
 861 
 862 
 863 --通常使用指定字段名的方式
 864 insert into student.Students(studentname,studid)
 865 values(alice,2)
 866 
 867 --另外一种写法
 868 insert student.Students(studid,studentname)
 869 select ‘‘,‘‘ union,
 870 select ‘‘,‘‘ union,
 871 select ‘‘,‘‘ union,
 872 select ‘‘,‘‘ union
 873 
 874 
 875 
 876 
 877 
 878 select * from student.Students;
 879 
 880 
 881 --事务和并发
 882 
 883 --隐式事务
 884 
 885 --显示事务,明确指出事务的起止边界
 886 begin transaction
 887 delete from Sales.Shippers where shipperid=4
 888 delete from Sales.Shippers where shipperid=5
 889 --回滚
 890 rollback 
 891 --提交
 892 commit
 893 
 894 --事务必须有四个属性
 895 --原子性(Atomicity),一致性(Consistency),隔离性(Isolation)
 896 --持久性(Durabillity) 这四个属性的首字母可以缩写成ACID
 897 
 898 
 899 --设置隔离级别可以读取未提交的数据 
 900 set transaction isolation level read uncommitted
 901 
 902 
 903 --其实就是加锁,加上共享锁
 904 --普通情况下,查询的时候,系统加上共享锁,查询结束,
 905 --锁撤销
 906 --我们现在,希望在查询结束之后,共享锁依然存在,保证数据不被修改
 907 
 908 set transaction isolation level repeatable read;
 909 
 910 
 911 
 912 
 913 --可编程对象
 914 --定义变量
 915 declare @i int
 916 set @i=10
 917 print @i;
 918 
 919 declare @i varchar(20)
 920 set @i=Hello,world;
 921 print @i;
 922 
 923 declare @i nchar(20) --固定长度
 924 set @i=Hello;      --已经占用了所有的空间
 925 set @i=@2+,world;
 926 print @i;
 927 
 928 --还可以使用select 对变量赋值
 929 select @i=99;
 930 print @i;
 931 
 932 --当前时间
 933 declare @now datetime
 934 set @now=getdate();
 935 print @now;
 936 
 937 
 938 --查询顾客的数量,保存到变量中使用
 939 declare @customerCount int;
 940 select @customerCount= count(*)   --赋值语句
 941 from Sales.Customers;
 942 print @customerCount;
 943 
 944 --选择结构
 945 --条件 
 946 --取得当前时间的分钟部分
 947 declare @mi int;
 948 set @mi=datepart(minute,getdate());
 949 if @mi>10
 950   begin 
 951     print 下课
 952   end
 953 else 
 954   begin
 955     print 继续学习
 956   end
 957   
 958 break
 959 
 960 
 961 
 962 --游标
 963 
 964 select companyname
 965 from sales.customers
 966 
 967 --简单变量,标量
 968 declare @name nvarchar(100)
 969 select @name=companyname
 970 from sales.customers;
 971 print @name;
 972 
 973 --使用游标   是把数据逐条查询出来
 974 --1. 声明游标,基于查询  
 975 declare c cursor
 976     for
 977     select custid, companyname
 978     from sales.customer
 979     
 980 declare @name nvarchar(100);
 981 declare @id int;
 982 --2.在使用之前,必须打开游标
 983 open c;
 984 --3. 从游标中读取查询数据,每次可以读取一条记录
 985 fetch next from c into @id,@name
 986 --4. 注意fetch 并不一定获取实际的数据
 987 while @@fetch_status=0   --成功获取了数据
 988 begin 
 989  print @name;
 990   -- 燃火,试探获取下一条数据
 991   fetch next from c into @id,@name;
 992 end
 993 --5. 游标使用完毕,一定要关闭
 994 close c;
 995 --6.释放游标
 996 deallocate c;
 997 
 998 
 999 --局部临时表  名字前面有一个#表示局部临时表
1000 create table #temptable
1001 (
1002   num  int
1003 )
1004 --使用与表相同
1005 insert into #temptable (num) values(1),(1),(2),(3),(5);
1006 
1007 --全局临时表
1008 --使用方式名字前面有两个##
1009 create table ##globaltable
1010 (
1011  name nvarchar(20)
1012 )
1013 --表变量
1014 declare @table table
1015 (
1016  num int
1017 )
1018 insert into @table (num) values(1),(1),(2),(3),(5)
1019 select * from @table
1020 
1021 --静态SQL 
1022 
1023 --动态SQL
1024 declare @sql nvarchar(200)
1025 set @sql=select companyname from seles.customers
1026 print @sql;
1027 --将一个字符串看成一个SQL 语句动态执行
1028 exec(@sql);
1029 
1030 
1031 --sql 注入攻击
1032 
1033 declare @sql nvarchar(200);
1034 set @sql=select custid,companyname from seles.customers where
1035  custid=@id;
1036  
1037  --用户输入查询的编号
1038  declare @input int;
1039  set @input=23;
1040  --原则,用户的输入是邪恶的
1041  --set @input=‘abc‘;
1042  --set @input=‘0 or 1=1‘;
1043  --set @input=‘0; select * from sales.customers‘;
1044  print @sql;
1045  
1046  --将一个字符串看成一个SQL 语句动态执行
1047  exec sp_executesql 
1048         @stmt=@sql;   --表示要执行的SQL语句
1049         @params= N@id as int;  --声明命令中需要的参数
1050         @id=@input;  --后面依次提供参数
1051  go
1052  
1053 
1054 --调整价格写成一段程序,保存到数据库中
1055 --存储过程
1056 create procedure ModifyPrice
1057 (
1058   @num  money 
1059 )
1060 as 
1061 update production products
1062         set unitprice=unitprice=@num;
1063 
1064 --存储过程保存在数据库中
1065 exec dbo.ModifyPrice @num=10;
1066 
1067 --参数问题
1068 --1.传入参数
1069 --  传统的参数,默认的参数就是传入参数
1070 --2.传出参数
1071 --  out,ref 参数
1072 
1073 --查询顾客的数量
1074 --与方法不同,存储过程没有通常意义上的返回类型和返回值
1075 create procedure GetCustomerCount
1076 (
1077 @count int output  --参数有output 传出参数
1078 )
1079 as 
1080 declare @num int;
1081 select @num=count(*) from sales.customers;
1082 print @num;
1083 
1084 --使用带有传出参数的存储过程
1085 --必然使用变量来保存传出的结果
1086 declare @mycount int;
1087 --前面是参数定义的传出参数名称
1088 --后面是 我们定义的用来保存传出结果的变量
1089 exec dbo.GetCustomerCount @count=@mycount output;
1090 print @mycount
1091 
1092 
1093 create procedure createuser
1094 (
1095  @username nvarchar(100)
1096 )
1097  as 
1098     declare @namelen int;
1099     set @namelen=len(@username)
1100     if @namelen>=5
1101        return 0
1102     else 
1103        return 1;
1104        
1105 --调用 获取返回结果是否成功
1106 declare @returnValue int;
1107 exec @returnValue=createuser @username=23423432
1108 print @returnValue
1109 
1110 --创建函数
1111 create function getminute
1112 (
1113  @datevalue datetime   --传入参数
1114 )
1115 --函数可以直接返回一个值
1116 returns int
1117 as
1118  --函数体
1119 begin
1120    declare @mi int
1121    set @mi=datepart(minute,@datevalue);
1122    return @mi;
1123 end
1124 
1125 --调用
1126 select dbo.getminute(getdate())
1127 
1128 --触发器
1129 --创建一个日志表,记录对货运的操作
1130 create table shipper_log
1131 (
1132  logid int identity(1,1) primary key,
1133  opdate datetime default getdate(),
1134  opuse nvarchar(20),
1135  op nvarchar(20),
1136  shipname nvarchar(50),
1137  shipphone nvarchar(20)
1138  )
1139  --创建一个审核货运公司的触发器
1140  create trigger tg_ship 
1141  --触发器没有参数,由于通过数据库系统调用
1142  on Sales.Shippers after insert,delete,update
1143  as
1144    insert into shipper_log(opuse,op,shipname,shipphone)
1145    select user_name(),插入,companyname,phone
1146    from inserted;
1147  
1148 --标识问题
1149 --获得系统提供的标识值,获取整个系统系统范围内
1150 select @@identity
1151 
1152 --应该使用这个,获取当前作用域中最新生成的标识值
1153 select scope_identity();
1154  
1155  
1156 select datepart(day,20161228,20140624)
1157 
1158 --多表查询
1159 with 
1160 a as (select 60000 cw1, 200 cw2, 2010-12-31 cw3),
1161 b as (select 60000 CW1, 银行 CW2),
1162 c as (select 银行 cw1, 121 cw2, 2010-12-31 CW3)
1163 select a.cw1 公司,a.cw2 财务,b.CW2 行业,c.cw2 平均值 
1164 from a
1165 inner join b on a.cw1=b.CW1
1166 inner join c on b.CW2=c.cw1
1167 where a.cw2>c.cw2
1168 
1169 --参照更新格式
1170 update a
1171 set a.字段=b.字段
1172 from a join b on a.xx=b.xx
1173 where
1174 
1175 --查询表中重复的数据
1176 select 字段,sun(1) as c
1177 from1178 group by 字段
1179 having sum(1)>1

 

T-SQL基本语法

标签:

原文地址:http://www.cnblogs.com/sunxuchu/p/5333148.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!