设为首页 收藏本站
查看: 898|回复: 0

[经验分享] SQL Server -- 如何书写优雅、漂亮的SQL脚本?

[复制链接]

尚未签到

发表于 2018-10-15 13:28:42 | 显示全部楼层 |阅读模式
  From: http://www.cnblogs.com/kerrycode/archive/2010/08/16/1800334.html
  本篇来聊聊如何书写漂亮、整洁、优雅的SQL脚本,下面这些是我个人总结、整理出来的。姑且做个抛砖引玉吧,呵呵,欢迎大家一起来讨论。
  我们首先来看看一段创建数据表的脚本(如下所示),你是否觉得有什么不妥或是不足呢?如果是你,你怎样书写呢?


  CREATE TABLE [dbo].[TableDataDictionary](
  [TableID] [int] IDENTITY(1,1) NOT NULL,
  [IpAddress] [nvarchar](15) NOT NULL,
  [DataBaseName] [nvarchar](35) NOT NULL,
  [TableName] [nvarchar](35) NOT NULL,
  [Description] [nvarchar](150) NULL,
  CONSTRAINT [PK_TableDataDictionary] PRIMARY KEY([Tableid])
  )

  可能你也没有觉得它有什么不妥,因为你一直都是这样书写哦。而且更混乱、更杂的的脚本你也见过,也可能习惯了;那么来看看下面的脚本,


  USE [Test];
  GO
  IF OBJECT_ID(N'TableDataDictionary') IS NULL
  CREATE TABLE [dbo].[TableDataDictionary]
  (
  [TableID]            INT IDENTITY(1,1)  NOT NULL,
  [IpAddress]          NVARCHAR(15)       NOT NULL,
  [DataBaseName]       NVARCHAR(35)       NOT NULL,
  [TableName]          NVARCHAR(35)       NOT NULL,
  [Description]        NVARCHAR(150)      NULL,
  CONSTRAINT [PK_TableDataDictionary] PRIMARY KEY([Tableid])
  );
  ELSE
  PRINT 'This table have been exist in database';
  GO

  上面两段脚本比起来,你是否觉得下面的更美观、优雅呢?
  接下来我们来看看四段申明变量的脚本,自己可以对比


  (一)
  DECLARE @PayType VARCHAR(50),  @Rate FLOAT, @FeeRate FLOAT ,@OtheFee FLOAT;
  DECLARE @StartDate DATETIME,   @EndDate DATETIME;
  DECLARE @CmdSql NVARCHAR(MAX);
  DECLARE @MyCardBillFee FLOAT, @MyCardFee    FLOAT;
  ---------------------------------------------------------------------------------------------------------
  (二)
  DECLARE @PayType VARCHAR(50);
  DECLARE @Rate FLOAT;
  DECLARE @FeeRate FLOAT;
  DECLARE @OtheFee FLOAT;
  DECLARE @StartDate DATETIME;
  DECLARE @EndDate DATETIME;
  DECLARE @CmdSql NVARCHAR(MAX);
  DECLARE @MyCardBillFee FLOAT;
  DECLARE @MyCardFee    FLOAT;
  ---------------------------------------------------------------------------------------------------------
  (三)
  DECLARE @PayType         VARCHAR(50);              --支付类型
  DECLARE @Rate            FLOAT;                    --汇率比例
  DECLARE @FeeRate         FLOAT;                    --手续费比例
  DECLARE @MyCardFee       FLOAT;                    --......
  DECLARE @OtheFee         FLOAT;                    --......
  DECLARE @MyCardBillFee   FLOAT;                    --......
  DECLARE @StartDate       DATETIME;                 --......
  DECLARE @EndDate         DATETIME;                 --......
  DECLARE @CmdSql          NVARCHAR(MAX);            --......
  ---------------------------------------------------------------------------------------------------------
  (四)
  DECLARE
  @PayType         AS    VARCHAR(50);            --支付类型
  @Rate            AS    FLOAT;                  --汇率比例
  @FeeRate         AS    FLOAT;                  --手续费比例
  @MyCardFee       AS    FLOAT;                  --......
  @OtheFee         AS    FLOAT;                  --......
  @MyCardBillFee   AS    FLOAT;                  --......
  @StartDate       AS    DATETIME;               --......
  @EndDate         AS    DATETIME;               --......
  @CmdSql          AS    NVARCHAR(MAX);          --......
  -------------------------------------------------------------------------------------------------------

  如果是你,你愿意运用哪种书写格式呢? 个人觉得(一)写得极极糟糕,不仅阅读不方便、而且也不方便注视。(二)则是我以前习惯书写的格式,一来没有注视、二来看起来没有(三)、(四)美观、大方。
  存储过程、函数头部注视的样式(个人曾今用过的样式):


  (一)
  --=============================================================================================================
  --            Function        :            dbo.USP_GetEmployeById 按Id获取雇员信息
  --            Auhtor            :            Kerry
  --            Create Date       :            2010-08-12
  --            Description       :            详细描述存储过程功能(对Function 功能补充)、以及参数、输出结果的描述
  --=============================================================================================================
  --            2010-08-12        :           修改....增加........
  --            2010-08-13        :            修改....增加.......
  --=============================================================================================================
  Function  简要描述存储过程、函数功能。
  Desctiption 详细描述存储过程、函数功能,以及参数、输出结果描述
  (二)
  --=============================================================================================================
  --        Create Date            :        2010-08-11
  --        Author                 :        Kerry
  --        Modified Date          :        2010-08-12
  --        Modified Content       :        修改表字段、增加汇率计算.....
  --        Modified Date          :        2010-08-13
  --        Modified Content       :        修改表字段、增加汇率计算.....
  --        Description            :        计算抢车位社区游戏的月充值结构信息。
  --=============================================================================================================
  (三)
  /**************************************************************************************************************
  Auhtor                 :            Kerry
  Create Date            :            2010-08-12
  Modified Date          :
  Modified Content       :
  Description            :            如何书写漂亮、优雅的SQL脚本
  **************************************************************************************************************/
  ( 四)
  -- =============================================
  -- Author:        
  -- Create date:
  -- Description:   
  -- =============================================
  使用MSSMS新建存储过程,它自动生成的样式

  个人觉得(一) >= (二) > (三) > (四) ,不知道大家有没有更好的格式推荐。
  下面看看这样一段脚本,一眼就觉得有点糟糕,其实实际开发中脚本比这个可能复杂得多,头痛吧

  select PermissionID from  Permission where resourceid=
  ( select top 1 resourceid from [Resource] where resourcename=@resourcename) and
  actionid=(select top 1 actionid from [Action] where actionname=@actionname)
  AND SchemaId in (SELECT SchemaId FROM dbo.BindToSchema WHERE DcUserID=@UserID)
  首先就应该统一关键字大小写,不要一部分大写、一部分小写。然后从结构上面调整。 可能每个人的审美观、习惯的格式不同,这个无所谓,也没有必要统一。 但是你书写出来的脚本至少要结构清晰,一目了然。不要让别人费很大的劲去调整格式,然后才能理解它的逻辑,如果写出上面或是比上面更糟糕的脚本,我想项目经理真应该教训教训你。这样只会给后来维护的人痛苦不堪(实际开发中可能比这糟糕十倍呢,想必很多人是深受其害啊)


  SELECT Permission FROM  Permission
  WHERE
  resourceid =( SELECT TOP 1 resourceid FROM [Resource] WHERE resourcename=@resourcename)
  AND actionid =(SELECT TOP 1 actionid FROM [Action] WHERE actionname=@actionname)
  AND SchemaId IN (SELECT SchemaId FROM dbo.DcUserBindToSchema WHERE DcUserID=@UserID)

  动态组合语句是否让你的脚本看起来林乱不堪啊,你有没有试过让其在某些方面看起来美观点、优雅点啊、


  'SELECT   Order_ID = @OrderID, CampaignCode= @CampaignCode, ProductCode = @ProductCode, StartDate= SpotDate,
  EndDate = EndDate, StartTime= Media_StartTime, EndTime = Media_EndTime, Duration = (CASE WHEN Media_Duration IS NULL OR   ELSE Media_Duration END), Adformat= Media_Adformat , Color = Media_Color , --Media_Showing,                                          Size   = Media_Size, SpotType  = Media_SpotType, URL = Media_URL  , ScheduleNo   = ScheduleNo ,
  Plan_Insertion_ID  = Plan_Insertion_ID
  那下面书写格式是不是美观、整洁些呢
  SELECT
  Order_ID          = @OrderID
  , CampaignCode      = @CampaignCode
  , ProductCode       = @ProductCode
  , StartDate         = SpotDate
  , EndDate           = EndDate
  , StartTime         = Media_StartTime
  , EndTime           = Media_EndTime
  , Adformat          = Media_Adformat
  , Color             = Media_Color
  , Impression        = Media_Impression
  , Location          = Media_Location
  , Material          = Media_Material
  , Position          = Media_Position
  , Program           = Media_Program
  , Scale             = Media_Scale         --Media_Showing
  , Size              = Media_Size
  , SpotType          = Media_SpotType
  , URL               = Media_URL
  , ScheduleNo       = ScheduleNo
  , Plan_Insertion_ID = Plan_Insertion_ID
  , Position = Media_Position
  '

  怎么样是否觉得下面的”清新脱俗“,眼前一亮啊,呵呵,不是在说美女啊。看看我以前一个同事写的吧,我只截取了一部分。

  写着觉得有点天马行空、不着边际了,其实这个话题有点大,而且和个人习惯、审美观有莫大联系,所谓众口难调,不过有几点应该是一致的:
  1:书写脚本的时候,多用空格、Tab键,不要让代码拥挤,杂糅在一起。
  2:让代码看起来觉得舒服,一目了然,不要一看就觉得头痛,要细细看上好久,才了解逻辑结构
  3:让代码看起来整洁、优美。凌乱不堪是大忌。
  4:总结、学习一些书写漂亮的格式。
  限于篇幅,下面给出一些我见过的、写的比较优雅的脚本,大家也可以贴出自己写得优美的代码,一起学习探讨。


  -- Construct column list
  SET @sql =
  N'SET @result = '                                    + @newline +
  N'  STUFF('                                          + @newline +
  N'    (SELECT N'','' + '
  + N'QUOTENAME(pivot_col) AS [text()]'       + @newline +
  N'     FROM (SELECT DISTINCT('
  + @on_cols + N') AS pivot_col'              + @newline +
  N'           FROM' + @query + N') AS DistinctCols'   + @newline +
  N'     ORDER BY pivot_col'                           + @newline +
  N'     FOR XML PATH('''')),'                         + @newline +
  N'    1, 1, N'''');'
  EXEC sp_executesql
  @stmt   = @sql,
  @params = N'@result AS NVARCHAR(MAX) OUTPUT',
  @result = @cols OUTPUT;
  -- Create the PIVOT query
  SET @sql =
  N'SELECT *'                                           + @newline +
  N'FROM'                                               + @newline +
  N'  ( SELECT '                                        + @newline +
  N'      ' + @on_rows + N','                           + @newline +
  N'      ' + @on_cols + N' AS pivot_col,'              + @newline +
  N'      ' + @agg_col + N' AS agg_col'                 + @newline +
  N'    FROM '                                          + @newline +
  N'      ' + @query                                    + @newline +
  N'  ) AS PivotInput'                                  + @newline +
  N'  PIVOT'                                            + @newline +
  N'    ( ' + @agg_func + N'(agg_col)'                  + @newline +
  N'      FOR pivot_col'                                + @newline +
  N'        IN(' + @cols + N')'                         + @newline +
  N'    ) AS PivotOutput;'



  DECLARE
  @schemaname AS NVARCHAR(128),
  @tablename  AS NVARCHAR(128),
  @colname    AS NVARCHAR(128),
  @sql        AS NVARCHAR(805);
  SET @schemaname = N'dbo';
  SET @tablename  = N'Orders';
  SET @colname    = N'CustomerID';
  SET @sql = N'SELECT COUNT(DISTINCT '
  + QUOTENAME(@colname) + N') FROM '
  + QUOTENAME(@schemaname)
  + N'.'
  + QUOTENAME(@tablename)
  + N';';
  EXEC(@sql);
  备注:相关SQL Format工具(SQLPrompt_6.3.0.344)
  http://www.liangchan.net/soft/softdown.asp?softid=6080


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-621975-1-1.html 上篇帖子: SQL Server通过web方式进行远程维护,管理 下篇帖子: SQL Server -- MYSQL auto-increment,MS SQL Identity,Access,Oracle
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表