Tim*_*mbo 54 sql sql-server formatting standards coding-style
在我上一份工作中,我们开发了一个数据库非常繁重的应用程序,并且我开发了一些格式化标准,以便我们都可以使用通用布局编写SQL.我们还开发了编码标准,但这些标准更具有平台特性,所以我不会在这里讨论它们.
我很想知道其他人使用什么SQL格式标准.与大多数其他编码环境不同,我没有在网上找到很多共识.
要涵盖主要查询类型:
select
ST.ColumnName1,
JT.ColumnName2,
SJT.ColumnName3
from
SourceTable ST
inner join JoinTable JT
on JT.SourceTableID = ST.SourceTableID
inner join SecondJoinTable SJT
on ST.SourceTableID = SJT.SourceTableID
and JT.Column3 = SJT.Column4
where
ST.SourceTableID = X
and JT.ColumnName3 = Y
Run Code Online (Sandbox Code Playgroud)
有一些分歧关于行后饲料select,from和where.选择行的意图是允许其他运算符,例如"top X"而不改变布局.接下来,只需在关键查询元素之后保持一致的换行符,就可以获得良好的可读性.
滴药后换行from,并where会是一个可以理解的版本.但是,在update下面的查询中,我们看到后面的换行为where我们提供了良好的列对齐.同样,换行后group by或order by保持我们的列布局清晰易读.
update
TargetTable
set
ColumnName1 = @value,
ColumnName2 = @value2
where
Condition1 = @test
Run Code Online (Sandbox Code Playgroud)
最后,一个insert:
insert into TargetTable (
ColumnName1,
ColumnName2,
ColumnName3
) values (
@value1,
@value2,
@value3
)
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,这些并没有偏离MS SQL Server管理工作室 /查询分析器写出SQL的方式,但它们确实有所不同.
我期待看到Stack Overflow社区中是否就此主题达成了共识.我经常惊讶于有多少开发人员可以遵循其他语言的标准格式,并在遇到SQL时突然变得如此随机.
小智 22
迟到的答案,但希望有用.
我作为大型开发团队的一员工作的经验是,您可以继续定义您喜欢的任何标准,但问题实际上是强制执行这些或使开发人员很容易实现.
作为开发人员,我们有时创建一些有用的东西然后说"我稍后会格式化",但后来永远不会出现.
最初,我们使用了SQL Prompt(很棒),但后来切换到ApexSQL Refactor,因为它是一个免费的工具.
yuk*_*ude 18
我迟到了,但我只是添加了我喜欢的格式化风格,我必须从书本和手册中学到:它很紧凑.这是示例SELECT声明:
SELECT st.column_name_1, jt.column_name_2,
sjt.column_name_3
FROM source_table AS st
INNER JOIN join_table AS jt USING (source_table_id)
INNER JOIN second_join_table AS sjt ON st.source_table_id = sjt.source_table_id
AND jt.column_3 = sjt.column_4
WHERE st.source_table_id = X
AND jt.column_name_3 = Y
Run Code Online (Sandbox Code Playgroud)
简而言之:8个空格的缩进,大写字母中的关键字(虽然小写时它们的颜色更好),没有camelcase(在Oracle上没有意义),并且在需要时换行.
的UPDATE:
UPDATE target_table
SET column_name_1 = @value,
column_name_2 = @value2
WHERE condition_1 = @test
Run Code Online (Sandbox Code Playgroud)
而且INSERT:
INSERT INTO target_table (column_name_1, column_name_2,
column_name_3)
VALUES (@value1, @value2, @value3)
Run Code Online (Sandbox Code Playgroud)
现在,让我成为第一个承认这种风格存在问题的人.8空格缩进意味着ORDER BY并且GROUP BY不对齐缩进,或者将单词BY本身分开.缩进WHERE子句的整个谓词也是更自然的,但我通常在左边缘对齐跟随AND和OR运算符.包裹INNER JOIN线后缩进也有些随意.
但无论出于何种原因,我仍然觉得它比其他选择更容易阅读.
我将使用这种格式化风格完成我最近的一个更复杂的创作.几乎所有你在SELECT声明中遇到的东西都出现在这一个中.(它也被改变以掩盖它的起源,我可能在这样做时引入了错误.)
SELECT term, student_id,
CASE
WHEN ((ft_credits > 0 AND credits >= ft_credits) OR (ft_hours_per_week > 3 AND hours_per_week >= ft_hours_per_week)) THEN 'F'
ELSE 'P'
END AS status
FROM (
SELECT term, student_id,
pm.credits AS ft_credits, pm.hours AS ft_hours_per_week,
SUM(credits) AS credits, SUM(hours_per_week) AS hours_per_week
FROM (
SELECT e.term, e.student_id, NVL(o.credits, 0) credits,
CASE
WHEN NVL(o.weeks, 0) > 5 THEN (NVL(o.lect_hours, 0) + NVL(o.lab_hours, 0) + NVL(o.ext_hours, 0)) / NVL(o.weeks, 0)
ELSE 0
END AS hours_per_week
FROM enrollment AS e
INNER JOIN offering AS o USING (term, offering_id)
INNER JOIN program_enrollment AS pe ON e.student_id = pe.student_id AND e.term = pe.term AND e.offering_id = pe.offering_id
WHERE e.registration_code NOT IN ('A7', 'D0', 'WL')
)
INNER JOIN student_history AS sh USING (student_id)
INNER JOIN program_major AS pm ON sh.major_code_1 = pm._major_code AND sh.division_code_1 = pm.division_code
WHERE sh.eff_term = (
SELECT MAX(eff_term)
FROM student_history AS shi
WHERE sh.student_id = shi.student_id
AND shi.eff_term <= term)
GROUP BY term, student_id, pm.credits, pm.hours
)
ORDER BY term, student_id
Run Code Online (Sandbox Code Playgroud)
这种憎恶计算学生在特定学期是全职还是兼职.无论风格如何,这个都难以阅读.
Joh*_*som 17
我认为只要你能轻松阅读源代码,格式就是次要的.只要实现了这个目标,就可以采用一些好的布局样式.
对我来说唯一重要的另一个方面是,无论您选择在商店中采用何种编码布局/样式,都要确保所有编码人员始终如一地使用它.
仅供您参考,以下是我将如何呈现您提供的示例,以及我的布局首选项.特别值得注意的是,该ON子句与连接中的join主要连接条件(即密钥匹配)在同一行上,并且其他条件被移动到where子句中.
select
ST.ColumnName1,
JT.ColumnName2,
SJT.ColumnName3
from
SourceTable ST
inner join JoinTable JT on
JT.SourceTableID = ST.SourceTableID
inner join SecondJoinTable SJT on
ST.SourceTableID = SJT.SourceTableID
where
ST.SourceTableID = X
and JT.ColumnName3 = Y
and JT.Column3 = SJT.Column4
Run Code Online (Sandbox Code Playgroud)
一个提示,从Red Gate获取SQL Prompt的副本.您可以自定义工具以使用所需的布局首选项,然后您商店中的编码人员都可以使用它来确保每个人都采用相同的编码标准.
迟到了,但我会把我的帽子扔进戒指里。写作需要更长的时间,但我发现垂直对齐会出现模式,一旦你习惯了它就会变得非常易读。
SELECT ST.ColumnName1,
JT.ColumnName2,
SJT.ColumnName3,
CASE WHEN condition1 = True
AND condition2 = True Then DoSomething
Else DoSomethingElse
END ColumnName4
FROM SourceTable AS ST
INNER
JOIN JoinTable AS JT
ON JT.SourceTableID = ST.SourceTableID
INNER
JOIN SecondJoinTable AS SJT
ON ST.SourceTableID = SJT.SourceTableID
AND JT.Column3 = SJT.Column4
LEFT
JOIN (SELECT Column5
FROM Table4
QUALIFY row_number() OVER
( PARTITION BY pField1,
pField2
ORDER BY oField1
) = 1
) AS subQry
ON SJT.Column5 = subQry.Column5
WHERE ST.SourceTableID = X
AND JT.ColumnName3 = Y
Run Code Online (Sandbox Code Playgroud)
我正在用 C# 编写开源 SQL 格式化程序(现阶段仅限 SQL Server),因此我通过它完成了上述查询。
它采用与 OP 类似的策略,即每个“部分”在其下方都有缩进的子元素。如果需要,我会在部分之间添加空白以帮助清晰——当没有连接或最小 where 条件时,不会添加这些空白。
结果:
SELECT
ST.ColumnName1,
JT.ColumnName2,
SJT.ColumnName3
FROM SourceTable ST
INNER JOIN JoinTable JT
ON JT.SourceTableID = ST.SourceTableID
INNER JOIN SecondJoinTable SJT
ON ST.SourceTableID = SJT.SourceTableID
AND ST.SourceTable2ID = SJT.SourceTable2ID
WHERE ST.SourceTableID = X
AND JT.ColumnName3 = Y
AND JT.Column3 = SJT.Column4
ORDER BY
ST.ColumnName1
Run Code Online (Sandbox Code Playgroud)
SELECT
a.col1 AS [Column1]
,b.col2 AS [Column2]
,c.col1 AS [Column3]
FROM
Table1 a
INNER JOIN Table2 b ON b.Id = a.bId
INNER JOIN Table3 c ON c.Id = a.cId
WHERE
a.col = X
AND b.col = Y
Run Code Online (Sandbox Code Playgroud)
使用的行比这里的许多示例多得多,但我觉得它更容易理解,可以快速删除列/子句/表格。它有助于利用垂直定向的显示器。
真好 作为Python程序员,这是我的偏好:
之后的换行符select,from并且where仅在需要可读性时才使用。
当代码可以更紧凑且可读性更好时,我通常更喜欢更紧凑的形式。能够在一个屏幕中容纳更多代码,从而提高了生产率。
select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3
from SourceTable ST
inner join JoinTable JT
on JT.SourceTableID = ST.SourceTableID
inner join SecondJoinTable SJT
on ST.SourceTableID = SJT.SourceTableID
and JT.Column3 = SJT.Column4
where ST.SourceTableID = X and JT.ColumnName3 = Y
Run Code Online (Sandbox Code Playgroud)
最终,这将是在代码检查期间进行的判断调用。
对于insert,我将括号放在不同的位置:
insert into TargetTable (
ColumnName1,
ColumnName2,
ColumnName3)
values (
@value1,
@value2,
@value3)
Run Code Online (Sandbox Code Playgroud)
这种格式的理由是,如果SQL将缩进用于块结构(如Python),则不需要括号。因此,如果仍然使用缩进,则括号应该对布局的影响最小。这是通过将它们放置在行的末尾来实现的。