sqlserver常用知识点备忘录

 背景

  一个项目的开发,离不开数据库的相关操作,表/视图设计,存储过程,触发器等等数据库对象的操作是非常频繁的。有时候,我们会查找系统中类似的代码,然后复制/粘贴进行再进行相应的修改。本文的目的在于归纳、总结sqlserver数据库的常用操作,并不断更新。期以备忘!

  P1 sql的执行顺序

  sql语句是操作数据库的工具,了解sql的执行顺序会极大地帮助我们提高我们编写的sql的执行效率。见以下代码:

  (8)SELECT (9)DISTINCT  (11)<Top Num> <select list>

  (1)FROM [left_table]

  (3)<join_type> JOIN <right_table>

  (2)ON <join_condition>

  (4)WHERE <where_condition>

  (5)GROUP BY <group_by_list>

  (6)WITH <CUBE | RollUP>

  (7)HAVING <having_condition>

  (10)ORDER BY <order_by_list>

  FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1

  ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2.

  OUTER(JOIN):如 果指定了OUTER JOIN(相对于CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。

  WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.

  GROUP BY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.

  CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.

  HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.

  SELECT:处理SELECT列表,产生VT8.

  DISTINCT:将重复的行从VT8中移除,产生VT9.

  ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10)。

  TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。

  总的来说,select的列是最后一步被执行的,而From的Table是首先被执行的。

  P2 创建带Try…Catch的存储过程模板

  Copy下面的代码,然后新建查询,就可以写sql语句,执行完后,一个你自己的存储过程就建立好了!

  USE [DB]--设定对应的数据库

  GO

  SET ANSI_NULLS ON

  GO

  SET QUOTED_IDENTIFIER ON

  GO

  -- =============================================

  -- AUTHOR:

  -- DESCRIBE:

  -- =============================================

  CREATE PROCEDURE [dbo].[UP_InsertJHBData]   --存储过程名

  (

  @CustomerName VARCHAR(50)             --参数

  )

  AS

  BEGIN

  SET NOCOUNT ON                     --提高性能的,必须要有

  DECLARE @Now DATETIME

  SET @Now = GETDATE()               --所有操作保证统一时间

  BEGIN TRY

  --在这里写SQL

  END TRY

  BEGIN CATCH

  DECLARE @ErrorMessage NVARCHAR(4000) ;

  DECLARE @ErrorSeverity INT ;

  DECLARE @ErrorState INT ;

  SELECT  @ErrorMessage = ERROR_MESSAGE() ,

  @ErrorSeverity = ERROR_SEVERITY() ,

  @ErrorState = ERROR_STATE() ;

  PRINT @ErrorMessage

  RAISERROR(@ErrorMessage,  -- Message text.

  @ErrorSeverity, -- Severity.

  @ErrorState     -- State.

  ) ;

  RETURN -1 ;

  END CATCH

  END

  P3 创建带事务的存储过程模板

  只是将带Try…Catch的存储过程的模板中加入了事务的控制,使用类似

  USE [DB]

  GO

  SET ANSI_NULLS ON

  GO

  SET QUOTED_IDENTIFIER ON

  GO

  -- =============================================

  -- AUTHOR:

  -- DESCRIBE:

  -- =============================================

  CREATE PROCEDURE [dbo].[UP_InsertJHBData]--存储过程名

  --参数

  (

  @CustomerName VARCHAR(50)

  )

  --参数

  AS

  BEGIN

  SET NOCOUNT ON ;--提高性能的,必须要有

  DECLARE @Now DATETIME ;

  SET @Now = GETDATE() ;--所有操作保证统一时间

  BEGIN TRY

  BEGIN TRANSACTION myTrans ;--开始事务

  --在这里写SQL

  COMMIT TRANSACTION myTrans ;--事务提交语句

  END TRY

  BEGIN CATCH

  ROLLBACK TRANSACTION myTrans-- 始终回滚事务

  --抛出异常

  DECLARE @ErrorMessage NVARCHAR(4000) ;

  DECLARE @ErrorSeverity INT ;

  DECLARE @ErrorState INT ;

  SELECT  @ErrorMessage = ERROR_MESSAGE() ,

  @ErrorSeverity = ERROR_SEVERITY() ,

  @ErrorState = ERROR_STATE() ;

  RAISERROR(@ErrorMessage,  -- Message text.

  @ErrorSeverity, -- Severity.

  @ErrorState     -- State.

  ) ;

  END CATCH

  END

P8 分组数据集并返回每个组的前n条记录

  Row_NUMBER()函数用于生成行号;利用PARTITION BY可以将结果集按照指定需求进行分组;最终使用一个简单的子查询就能够获取每组的前3条数据

  SELECT  *

  FROM    ( SELECT    ROW_NUMBER() OVER ( PARTITION BY ProductNO ORDER BY ProductNO ) AS RowNum ,

  *

  FROM      IM.dbo.ItemInfo

  ) t

  WHERE   t.RowNum IN ( 1, 2, 3 )

  P9 【用户自定义表类型】的使用

  您是否碰到过这样的需求:调用存储过程的时候传一张表进去???


  在sqlserver数据库中有一种称为【用户自定义表类型】的数据结构,类似表,存储过程的参数可以定义为【用户自定义表类型】,代码调用时可以直接传入一个List<T>,而存储过程调用时可以直接传入一个表变量。

  以下代码实现了在IM数据库中新建一个名称为GCRP_PendingGiftCard_TYPE的用户自定义表结构:

  USE [IM]

  GO

  /****** Object:  UserDefinedTableType [dbo].[GCRP_PendingGiftCard_TYPE]    Script Date: 04/08/2014 14:56:16 ******/

  CREATE TYPE [dbo].[GCRP_PendingGiftCard_TYPE] AS TABLE(

  [RowNum] [int] NULL,

  [GiftCardNO] [varchar](500) NULL,

  [UsedDate] [datetime] NULL,

  [CustomerName] [varchar](50) NULL,

  [ReduceAmount] [decimal](18, 2) NULL,

  [Amount] [decimal](18, 2) NULL

  )

  GO

  下面的代码演示了【用户自定义表类型】的使用方式和场景(使用起来和临时表、表变量类似)

  --1 声明一个自定义表类型@T_PendingGiftCard

  DECLARE @T_PendingGiftCard GCRP_PendingGiftCard_TYPE

  --2 执行一个存储过程,并把返回的结果集插入到上面声明的自定义表类型@T_PendingGiftCard中

  INSERT INTO @T_PendingGiftCard

  EXEC IM.dbo.UP_GCRP_GetEntireGfitCardWithReduceAmount

  --3 声明一个自定义表类型@T_PendingSO

  DECLARE @T_PendingSO GCRP_PendingSO_TYPE

  --4 执行一个存储过程,传入表类型@T_PendingGiftCard,并把返回的结果集插入自定义表类型@T_PendingSO中

  INSERT INTO @T_PendingSO

  EXEC IM.dbo.UP_GCRP_GetEntireSOWithGiftCardUsed

  @T_PendingGiftCard

  下面贴出这两个存储过程的源码,供大家参考

  View Code

  USE [IM]

  GO

  /****** Object:  StoredProcedure [dbo].[UP_GCRP_GetEntireSOWithGiftCardUsed]    Script Date: 04/08/2014 15:02:50 ******/

  SET ANSI_NULLS ON

  GO

  SET QUOTED_IDENTIFIER ON

  GO

  -- =============================================

  -- Author:        DeanZhou

  -- Create date: 2014-04-04

  -- Description:    获取礼品卡报表数据-获取使用礼品卡的订单信息

  -- =============================================

  ALTER PROCEDURE [dbo].[UP_GCRP_GetEntireSOWithGiftCardUsed]

  (

  @T_PendingGiftCard GCRP_PendingGiftCard_TYPE READONLY

  )

  AS

  BEGIN

  SET NOCOUNT ON ;--提高性能的,必须要有

  --订单状态:1 待审核 2 待支付 3 已支付,待确认 4 已支付 5 出库中 6 已发货 7 已收货 8 换货中 9 退货中

  --          10 已换货 11 已退货 12 退款成功 13 换货被拒绝 14 退货被拒绝 15 交易成功 16 订单已关闭 17 客户作废

  --          18 商城作废 19 系统自动作废 20 退款中 21 等待团购成功 22 组团失败

  SELECT  S.SONO ,                    -- 订单编号 VARCHAR(30)

  S.EwalletDiscountAmount ,    -- 电子钱包支付金额 DECIMAL(18,2)

  S.RefundAmount ,            -- 发生退款的总金额 DECIMAL(18,2)

  ( S.EwalletDiscountAmount + S.RefundAmount ) AS RealUsedAmount , -- 实际使用电子钱包的金额 DECIMAL(18,2)

  0 AS RelatedRefundID ,

  S.CustomerName ,            -- 客户名称 VARCHAR(50)

  S.SaleOrderStatus ,            -- 订单状态    INT

  S.CreateDate                -- 下单日期 DATETIME

  INTO    #T_PendingSO

  FROM    ( SELECT    A.SONO ,

  A.EwalletDiscountAmount ,

  ( SELECT    -ISNULL(SUM(B.Amount), 0)

  FROM      RMA.dbo.RefundRecord B

  WHERE     B.SONO = A.SONO

  AND B.RefundType = 3

 AND B.Status IN ( 2, 3, 4 )

  ) AS RefundAmount ,

  CONVERT(DECIMAL(18, 2), 0) AS RealUsedAmount ,

  A.CustomerName ,

  A.SaleOrderStatus ,

  A.CreateDate

  FROM      SO.dbo.SOMaster A

  WHERE     EwalletDiscountAmount > 0

  AND SaleOrderStatus NOT IN ( 1, 2, 17, 19 )

  AND EXISTS ( SELECT 1

  FROM   @T_PendingGiftCard C

  WHERE  A.CustomerName = C.CustomerName

  AND A.CreateDate > C.UsedDate )

  AND NOT EXISTS ( SELECT 1

  FROM   IM.dbo.Temp_UsedGiftCardReportDetail B

  WHERE  A.SONO = B.SONO

  AND B.UsedAmount > 0 )

  ) S

  DELETE IM.dbo.Temp_UsedGiftCardReportDetail WHERE UsedAmount <= 0 AND EXISTS (SELECT 1 FROM #T_PendingSO B WHERE Temp_UsedGiftCardReportDetail.SONO = B.SONO )

  SELECT  ROW_NUMBER() OVER ( ORDER BY S.CustomerName, S.SONO, S.CreateDate ASC ) AS RowNum ,

  S.*

  FROM    ( SELECT    *

  FROM      #T_PendingSO

  UNION ALL

  SELECT    A.SONO ,

  B.EwalletDiscountAmount ,

  -A.Amount AS RefundAmount ,

  B.RealUsedAmount ,

  A.RelatedRefundID ,

  B.CustomerName ,

  A.Status ,

  A.CreateDate

  FROM      RMA.dbo.RefundRecord A

  INNER JOIN #T_PendingSO B ON A.SONO = B.SONO

  WHERE     A.RefundType = 3

  AND A.Status IN ( 2, 3, 4 )

  UNION ALL

  SELECT    A.SONO ,

  0 AS EwalletDiscountAmount ,

  -A.Amount AS RefundAmount ,

  B.UsedAmount ,

  A.RelatedRefundID ,

  B.CustomerName ,

  A.Status ,

  A.CreateDate

  FROM      RMA.dbo.RefundRecord A

  INNER JOIN IM.dbo.Temp_UsedGiftCardReportDetail B ON A.SONO = B.SONO AND B.UsedAmount > 0

  WHERE     A.RefundType = 3

  AND A.Status IN ( 2, 3, 4 )

  ) S

  END

时间: 2024-08-03 07:10:07

sqlserver常用知识点备忘录的相关文章

Sqlserver常用的时间函数---GETDATE、GETUTCDATE、DATENAME

server|sqlserver|函数 Sqlserver常用的时间函数---GETDATE.GETUTCDATE.DATENAME Sqlserver常用的时间函数---GETDATE.GETUTCDATE.DATENAME作者:淘特网 日期: 2005-4-12 15:53:24 访问次数:出处:淘特网--http://www.tot.name 显示选项: 自动滚屏[左键停止]GETDATE按 datetime 值的 Microsoft SQL Server 标准内部格式返回当前系统日期和时

js+jquery常用知识点汇总

 本文主要介绍了jquery源码中常见的知识点以及javascript中原型链常见的知识点,非常的全面,这里推荐给小伙伴们.     一.jquery源码中常见的知识点 1.string,number类型转换的快捷方法   复制代码 代码如下: // @param s为字符串,n为数字 function fn(obj){ //转换为String类型 var s = obj +""; //转换为number类型 var n = +obj; }   分享一个面试例子: //加会将其后面自动

SqlServer 常用内置函数及用法

  SqlServer 常用内置函数及用法 select cast('2012/02/03' as datetime); select convert(varchar(10),GETDATE(),120);--转换成日期类型 select CASE WHEN ID =1 THEN 'A0' ELSE 'TT' END from demo1;--case when select len('ssa爱迪生') --返回6 长度 select left('seaa',2) --se从左边起前两个字符 s

js+jquery常用知识点汇总_javascript技巧

一.jquery源码中常见的知识点 1.string,number类型转换的快捷方法 复制代码 代码如下: // @param s为字符串,n为数字 function fn(obj){     //转换为String类型     var s = obj +"";     //转换为number类型     var n = +obj; } 分享一个面试例子: //加会将其后面自动转换成字符串 "64"+4="644" //减会将其自动转换成数字 &

jQuery常用知识点总结以及平时封装常用函数_jquery

本文为大家介绍了jQuery中常用知识点及函数,包含许多细节方面的知识,下面我们一起学习一下. jQuery中为我们提供了很多有用的属性,自己总结的一些常用的函数.个人认为在在线排盘开发中会比较常用的,仅供大家学习和参考. 刚开始学习前端的时候开始整理这个文档,现在内容已经逐渐增多.虽然现在看起来,文档里的内容非常简单,但是看着这些内容,好像还依稀记得这一行行代码当时被记录的情景.所以我想把这段回忆保存起来,为刚接触前端的童鞋们提供一个简单的查询的途径,也以此来缅怀我的前端学习之路. ** 此文

CodeIgniter常用知识点小结

本文简单总结了CodeIgniter开发中的常用知识点.分享给大家供大家参考,具体如下: 跳转: $this->load->helper('url'); redirect(); 常量定义: config/constants.php 关于语言文件: 只说我自己的做法 为了统一管理错误信息 决定做一个error_lang.php 在application/language下新建文件夹chinese 新建文件 error_lang.php 在config.php里: $config['languag

Sqlserver常用函数例子说明

在操作SQLServer的时候, 很多时候记不住具体的函数如何使用, 查找联机帮助还是嫌麻烦, 且有很多时候例子也不好懂, 下面对每个常用的函数用用例子说明,一目了然,你自己在数据库中执行一下,结果就知道什么回事了 --字符串功能--substringprint substring('iamagoodperson',1,5)select substring('iamagoodperson',1,5)--upperselect upper('he is a good person')--lower

JavaScript开发中的常用知识点

前言 最近在做项目的时候自己写了一些JavaScipt代码,于是自己又进行简单的查阅资料整理了一下,发现了如下几个比较有用的知识点: 1.三种声明函数的方式 2.jQuery $(document).ready() 与window.onload的区别 3.location.href 4.获取url中的参数 5.判断是否存在函数的方法 6.设置Iframe高度 7.解决文本框设置只读后按退键后退页面 1.三种声明函数的方式 1.声明式的函数 function functionName(arg1,

sqlserver常用命令行操作(启动、停止、暂停)_MsSql

启动sql server Net Start MSSqlServer 暂停sql server Net Pause MSSqlServer 重新启动暂停的sql server Net Continue MSSqlServer 停止sql server Net stop MSSqlServer 命令行方式修改sql server sa 的密码 一直都是使用企业管理器操作sql的,昨天帮一朋友部署网站,租的国外vps主机,登陆上去只看到sql的图标正常运行的,企业管理器和查询分析器的影都没看到,汗一