你遵循什么SQL编码标准?

时间:2009-02-06 21:56:51

标签: sql coding-style

那里有广泛使用的SQL编码标准吗? SQL与C / C ++类型的编程语言略有不同。真的不知道如何最好地格式化它以便于阅读。

14 个答案:

答案 0 :(得分:48)

不会称之为编码标准 - 更像是编码风格

SELECT
    T1.col1,
    T1.col2,
    T2.col3
FROM
    table1 T1
    INNER JOIN ON Table2 T2 ON T1.ID = T2.ID
WHERE
    T1.col1 = 'xxx'
    AND T2.Col3 = 'yyy'
  • 大写保留字
  • 新行上的主要关键字
  • 在列
  • 之前不能习惯逗号
  • 始终使用简短有意义的表别名
  • 使用v
  • 前缀视图
  • 使用sp前缀存储过程(但不要使用为内置过程保留的“sp_”)
  • 不添加前缀表
  • 表名单数

答案 1 :(得分:13)

我知道这很长,但请耐心等待,这很重要。这个问题打开了一个很酷的蠕虫病毒。如果您不喜欢数据库块,请继续阅读。

并且,在任何人想到打倒我的回复之前,看到以下文章和关于锁定的连接文章,并重新编译;两个最具破坏性的资源命中SQL数据库。

<强> http://support.microsoft.com/kb/263889

我可以很快打字,而且我不想输入下一个人。但是下面的要点非常密切,即使是更多的打字。我已经构建了自己的SP应用程序来为我做这件事。

我提出的要点非常重要!你甚至可以对自己说,“你在开玩笑,这不是问题”,好吧,那么你没有看过上面的文章。 AND ,M $将这些点放入NOTE中是完全愚蠢的。对我来说,这些问题应该是大胆和尖锐的。

我还做了很多编码来使用C#应用程序构建我的基本脚本来加速开发,这些实践非常合理(价值10年),使脚本SP更容易,特别快。

还有更多,但这是我为所有事情的前60%所做的事情。


最佳做法

  • 使用对象周围的括号,以便查询引擎在看到字段时明确地知道字段
  • 使用相同的案例作为表格对象名称和字段名称
  • 从应用程序调用SP时,请使用具有正确所有者和大小写的完全限定[dbo]。[procName]。不开玩笑!阅读上面的文章!
  • 引用对象的所有者,以便明确知道安全性,而不必弄清楚
  • 请勿使用“sp_”,因为这是指系统存储过程和开销
  • 使用SET NOCOUNT ON和SET NOCOUNT OFF消除额外开销,以跟踪存储过程中更新的记录数,除非您需要它们。通常,你没有,你可以获得巨大的性能提升。

偏好

  • 使用proc
  • 前缀存储过程
  • 使用SEL,UPD,DEL,INS(或SELECT,UPDATE,DELETE,INSERT)对每个存储过程进行后缀
  • 大写保留字
  • 新行上的主要关键字(脚本)
  • 在列之前使用逗号(脚本)
  • 使用vw
  • 的前缀视图
  • 不要为表添加前缀
  • 表名单数
  • 为标志名称添加后缀,例如“_ByPK”,“_ OrderByLastName”或“_Top15Orders”,以了解库存SP的变化

选择

CREATE PROC [dbo].[procTable_SEL]
AS
SET NOCOUNT ON
SELECT
    [Column1] = T1.[col1]
  , [Column2] = T1.[col2]
  , [Column3] = T2.[col3]
FROM [dbo].[Table] T1    
INNER JOIN ON [dbo].[Table2] T2 ON T1.ID = T2.ID
WHERE
      T1.[col1] = 'xxx'
  AND T2.[Col3] = 'yyy'
SET NOCOUNT OFF
GO

更新

CREATE PROC [dbo].[procTable_UPD]
AS
SET NOCOUNT ON
UPDATE t1 SET
    [Column1] = @Value1
  , [Column2] = @Value2
  , [Column3] = @Value3
FROM [dbo].[Table1] T1
INNER JOIN ON [dbo].[Table2] T2 ON T1.[ID] = T2.[ID]
WHERE
      T1.[col1] = 'xxx'
  AND T2.[Col3] = 'yyy'
SET NOCOUNT OFF
GO

插入

CREATE PROC [dbo].[procTable_INS]
AS
SET NOCOUNT ON
INSERT INTO [Table1] (
[Column1]
  , [Column2]
  , [Column3]
)
VALUES (
    @Value1
  , @Value2
  , @Value3
)
SET NOCOUNT OFF
GO

OR

CREATE PROC dbo.procTable_INS
AS
SET NOCOUNT ON
INSERT INTO [table1] (
    [Column1]
  , [Column2]
  , [Column3]
)
SELECT
    [Column1] = T1.col1
  , [Column2] = T1.col2
  , [Column3] = T2.col3
FROM dbo.Table1 T1    
INNER JOIN ON Table2 T2 ON T1.ID = T2.ID
WHERE
      T1.[col1] = 'xxx'
  AND T2.[Col3] = 'yyy'
SET NOCOUNT OFF
GO

删除

CREATE PROC dbo.procTable_DEL
AS
SET NOCOUNT ON
DELETE
FROM [dbo].[Table1] T1
INNER JOIN ON [dbo].[Table2] T2 ON T1.[ID] = T2.[ID]
WHERE
      T1.[col1] = 'xxx'
  AND T2.[Col3] = 'yyy'
SET NOCOUNT OFF
GO

答案 2 :(得分:12)

我喜欢前面的逗号:

SELECT
      column1
    , column2
    , column3
    , COALESCE(column4,'foo') column4
FROM
    tablename
WHERE
    column1 = 'bar'
ORDER BY 
      column1
    , column2

在我看来,这是最容易阅读和调试的。

答案 3 :(得分:7)

答案 4 :(得分:4)

来自PostgreSQL上一个非常好的博客,但这个主题一般适用:

Maintainable queries - my point of view (depesz.com)

  

......我决定编写可维护查询的优先级:

     
      
  1. 避免无用的打字。

  2.   
  3. 为表/视图使用别名。   总是。并使他们明智   别名。

  4.   
  5. 以某种方式缩进代码。

  6.   
  7. 避免引用(是的,这就是为什么我   讨厌Django)

  8.   
  9. 使用连接语法

  10.   

我同意保留字和其他所有标识符的大小写,除了我自己的标识符。

答案 5 :(得分:4)

我个人不喜欢用sp_前缀存储过程名称 - 它是多余的,IMO。相反,我喜欢在它们前面加上“功能单元”标识符。例如我将调用sprocs处理订单order_Save,order_GetById,order_GetByCustomer等。它将它们全部逻辑地分组在管理工作室中,并使得更难选择错误的订单。 (GetOrderByProduct,GetCustomerById等......)

当然,这是个人偏好,其他人可能更愿意把所有的蠢货放在一起,所有的拯救者等等。

只是我的2c。

答案 6 :(得分:2)

我通常每行保持很少,即:

select
    col1,
    col2,
    col3
from
    some_table tabl1
where
    col1 = 'some'
and 
(
    col2 = 'condition'
or  col2 = 'other'
)

答案 7 :(得分:2)

Google for sql pretty printer或look here。我自己没有尝试过,但它给你一个良好的开端。像Toad这样的大多数商业工具都有“格式化”选项,这也有帮助。

答案 8 :(得分:2)

使用www.sqlinform.com进行游戏 - 我建议您使用ANSI-92 standard,然后使用该网站了解它。

答案 9 :(得分:2)

SELECT c.id
     , c.name
     , c.folder
     , cs.num_users active_members
     , cs.num_videos

  FROM campaign c
  JOIN campaign_stats cs
    ON cs.campaign_id = c.id
  JOIN (SELECT _c.id
             , _c.name

          FROM campaign _c
         WHERE _c.type = 9) t_c 
    ON t_c.id = c.id

 WHERE c.id IN (1,2,3)
   AND cs.num_videos > 10

这对我们来说非常有用。

这个实际的查询没有多大意义,因为我试图快速构建它作为一个例子......但这不是重点。

  • t_c代表类别表子查询或“临时类别”。
  • _子查询中的东西。
  • 别名列名在查询的上下文中有意义。例如“active_members”
  • 将逗号放在新行的开头可以更容易地构建动态查询:

    $sql .= ", c.another_column"
    
  • 其他一切都很简单。

答案 10 :(得分:2)

蓝色的任何内容都是大写的SELECTDELETEGO

表名是单数的,就像保存客户表的表一样

链接表格为tablename_to_tablename

在表名和参数

中的作品之间使用_

示例

BEGIN
    SELECT
        Company.ID AS Company_ID,
        Company.Client_Name,
        Company.Website,
        Office.Office_Name
    FROM
        Company_Office WITH(NOLOCK)
        INNER JOIN Company WITH(NOLOCK) ON Company_Office.Company_ID = Company.ID
    WHERE
END

答案 11 :(得分:2)

我很惊讶我用了将近20年的编码风格不在此列表中:

  SELECT column1,
         column2,
         column3,
         COALESCE(column4, 'foo') AS column4
    FROM tablename
   WHERE column1 = 'bar'
ORDER BY column1,
         column2

我发现这绝对是最具可读性的,但我承认打字很乏味。如果正确对齐关键字太多,我会选择左对齐它们:

SELECT   column1,
         column2,
         column3,
         COALESCE(column4, 'foo') AS column4
FROM     tablename
WHERE    column1 = 'bar'
ORDER BY column1,
         column2

答案 12 :(得分:0)

要使用的数据类型: 我们应该只使用以下数据类型:

  • INT
  • BIGINT
  • SMALLINT
  • VARCHAR
  • BIT
  • DATETIME

为BIT数据类型提供默认值。它不应该是可空的 表名和列名永远不应为小写。它应该描述它的目的。避免使用简短形式。 在创建表FK和PK时要仔细考虑和定义。 变量名称应以一个/两个字母开头,表示其数据类型为小写。 对于例如INT变量应该以i开头。名称应该是描述性的,应避免使用简短形式。每个单词都应以大写字母开头,后跟所有小写字母。

E.g。

正确的方式: - iTotalCount

方式不正确: - xyz

应该对存储过程中与“WHERE”子句一起使用的表列进行索引/键控。这将提高数据处理的速度。 应该正确地对WHERE子句中的参数进行排序。主键/索引应位于位变量之前。 例如: - 在列组合(REF_ID,T_TYPE_STR,CNUMBER,TLOG_ID)上创建索引

- 在'WHERE'子句

中按顺序使用索引键的正确方法
SELECT REF_ID,T_TYPE_STR,C_NUMBER,TLOG_ID

FROM T_T_DATA_tbl

WHERE REF_ID = 1

AND LOG_ID = ‘4042654’

AND T_TYPE_STR = ‘SA’

AND CNUMBER = ‘10702’

–Incorrect way

SELECT REF_ID, T_TYPE_STR, CNUMBER, LOG_ID

FROM T_T_DATA_tbl

WHERE LOG_ID = ‘4042654’

AND T_TYPE_STR = ‘SA’

在编写存储过程时,我们应该在开头包含描述部分 作者:

创建日期:

说明

如果修改了任何sp,则此部分应附加

修改者:

修改日期:

说明

ROW_INSERTION_DATE_TIME和ROW_UPDATION_DATE_TIME列的默认值应为GETDATE()。

更多信息: http://www.writeulearn.com/sql-database-coding-standards/

答案 13 :(得分:-2)

create table
    #tempTable (
        col1 int,
        col2 int,
        col3 int
    )

insert into
    #tempTable (
        col1,
        col2,
        col3
    )
    select
        col1,
        col2,
        col3
    from
        Table3
        inner join Table2
            on Table1.col1 = Table2.col2
    where col1 = 5

select
    col2,
    case when col1 = 3
        then 'something'
        else 'somethingelse'
    end
from #tempTable
where
    col1 = 5
    and (
        col2 = 5
        or col3 in (
            select field
            from Table2
            where
                somecol = 2
                and othercol = 5
        )
    )