本篇来聊聊如何书写漂亮、整洁、优雅的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: <Author,,Name>
--
Create date: <Create Date,,>
--
Description: <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
);