在我上一份工作中,我们开发了一个数据库非常繁重的应用程序,并且我开发了一些格式化标准,以便我们都可以使用通用布局编写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
有一些分歧关于行后饲料select
,from
和where
.选择行的意图是允许其他运算符,例如"top X"而不改变布局.接下来,只需在关键查询元素之后保持一致的换行符,就可以获得良好的可读性.
滴药后换行from
,并where
会是一个可以理解的版本.但是,在update
下面的查询中,我们看到后面的换行为where
我们提供了良好的列对齐.同样,换行后group by
或order by
保持我们的列布局清晰易读.
update TargetTable set ColumnName1 = @value, ColumnName2 = @value2 where Condition1 = @test
最后,一个insert
:
insert into TargetTable ( ColumnName1, ColumnName2, ColumnName3 ) values ( @value1, @value2, @value3 )
在大多数情况下,这些并没有偏离MS SQL Server管理工作室 /查询分析器写出SQL的方式,但它们确实有所不同.
我期待看到Stack Overflow社区中是否就此主题达成了共识.我经常惊讶于有多少开发人员可以遵循其他语言的标准格式,并在遇到SQL时突然变得如此随机.
迟到的答案,但希望有用.
我作为大型开发团队的一员工作的经验是,您可以继续定义您喜欢的任何标准,但问题实际上是强制执行这些或使开发人员很容易实现.
作为开发人员,我们有时创建一些有用的东西然后说"我稍后会格式化",但后来永远不会出现.
最初,我们使用了SQL Prompt(很棒),但后来切换到ApexSQL Refactor,因为它是一个免费的工具.
我迟到了,但我只是添加了我喜欢的格式化风格,我必须从书本和手册中学到:它很紧凑.这是示例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
简而言之:8个空格的缩进,大写字母中的关键字(虽然小写时它们的颜色更好),没有camelcase(在Oracle上没有意义),并且在需要时换行.
的UPDATE
:
UPDATE target_table SET column_name_1 = @value, column_name_2 = @value2 WHERE condition_1 = @test
而且INSERT
:
INSERT INTO target_table (column_name_1, column_name_2, column_name_3) VALUES (@value1, @value2, @value3)
现在,让我成为第一个承认这种风格存在问题的人.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
这种憎恶计算学生在特定学期是全职还是兼职.无论风格如何,这个都难以阅读.
我认为只要你能轻松阅读源代码,格式就是次要的.只要实现了这个目标,就可以采用一些好的布局样式.
对我来说唯一重要的另一个方面是,无论您选择在商店中采用何种编码布局/样式,都要确保所有编码人员始终如一地使用它.
仅供您参考,以下是我将如何呈现您提供的示例,以及我的布局首选项.特别值得注意的是,该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
一个提示,从Red Gate获取SQL Prompt的副本.您可以自定义工具以使用所需的布局首选项,然后您商店中的编码人员都可以使用它来确保每个人都采用相同的编码标准.
真好 作为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
最终,这将是在代码检查期间进行的判断调用。
对于insert
,我将括号放在不同的位置:
insert into TargetTable ( ColumnName1, ColumnName2, ColumnName3) values ( @value1, @value2, @value3)
这种格式的理由是,如果SQL将缩进用于块结构(如Python),则不需要括号。因此,如果仍然使用缩进,则括号应该对布局的影响最小。这是通过将它们放置在行的末尾来实现的。