• SQL 语法书写准则


    1、准则目的

    使公司内部的 SQL 语法统一规范;
    便于项目团队相关人员的查看、修改;
    提高存储过程执行效率,避免 SQL 语法错误导致服务器效率低而产生系统问题;

    2、书写注释规范

    2.1 签名、日期、用途
    说明:每个存储过程必须要标明存储过程的编写者、编写日期、用途。
    示例:
    -- =============================================
    -- Author:
    -- Create date: <2022.8.13>
    -- Description:
    -- Rev: 10.00 同时汇总各需求项的是否完成装配的状态
    -- =============================================

    2.2 局部变量的注释说明
    说明:创建局部变量时,请标明变量的用途。
    示例:
    declare @IsMOItem char(1) --装配参照清单类型,1-参照工单进行装配,0-参照BOM进行装配

    2.3 表变量、临时表的字段说明
    说明:创建表变量或临时表时,请标明表、字段的用途。

    2.4 段落缩进注释
    说明:注释每一段代码的作用,便于查阅理解代码含义。
     

    1. Declare @IsStartLot bit
    2. DECLARE table_cur CURSOR FOR
    3. SELECT LineSequence,IsStartLot from @AssyBOMItem
    4. --用游标循环
    5. OPEN table_cur
    6. FETCH NEXT FROM table_cur INTO @LineSequence,@IsStartLot
    7. WHILE @@fetch_status = 0
    8. BEGIN
    9. IF @@fetch_status = -2
    10. CONTINUE
    11. if @IsStartLot=1
    12. begin --保留制自件,但删下层物料
    13. update @AssyBOMItem set IsDelete=1
    14. where LineSequence like @LineSequence+'%'
    15. end
    16. else
    17. begin --删自制件,但保留下层物料
    18. if exists(select LineSequence from @AssyBOMItem where LineSequence
    19. like @LineSequence+'%')
    20. update @AssyBOMItem set IsDelete=1
    21. where LineSequence=@LineSequence
    22. end
    23. FETCH NEXT FROM table_cur INTO @LineSequence,@IsStartLot
    24. END
    25. DEALLOCATE table_cur

    3、SQL 影响执行效率的注意点

    1. 3.1 Where 语句书写及效率影响
    2. 示例【1】:
    3. 在下面两条select语句中:
    4. select * from table1 where field1<=10000 and field1>=0;
    5. select * from table1 where field1>=0 and field1<=10000;
    6. 说明【1】:
    7. 如果数据表中的数据 field1 都>=0,则第一条 select 语句要比第二条 select
    8. 语句效率高的多,因为第二条 select 语句的第一个条件耗费了大量的系统资源。
    9. 原则:在 where 子句中应把最具限制性的条件放在最前面。
    10. 示例【2】:
    11. 在下面两条select语句中:
    12. select * from tab where a=...and b=...and c=...;
    13. 说明【2】:
    14. 若有索引 index(a,b,c),则 where 子句中字段的顺序应和索引中字段顺序一致。
    15. 原则:where 子句中字段的顺序应和索引中字段顺序一致。
    16. 示例【3】:
    17. 以下假设在field1上有唯一索引I1,在field2上有非唯一索引I2。
    18. select field3,field4 from tb where field1='sdf'
    19. select * from tb where field1='sdf'
    20. 说明【3】:
    21. 因为后者在索引扫描后要多一步 ROWID 表访问
    22. 示例【4】:
    23. 在下面两条select语句中:
    24. select field3,field4 from tb where field1>='sdf'
    25. select field3,field4 from tb where field1>'sdf'
    26. 说明【4】:
    27. 因为前者可以迅速定位索引。
    28. 示例【5】:
    29. 在下面select语句:
    30. select field3,field4 from tb where upper(field2)='RMN'不使用索引。
    31. 说明【5】:
    32. 如果一个表有两万条记录,建议不使用函数;如果一个表有五万条以上记录,
    33. 严格禁止使用函数!两万条记录以下没有限制。例如:Subtring、Like、Datepart
    34. 函数会降低搜索效率。
    35. 示例【6】:
    36. select field3,field4 from tb where field2!='TOM'不使用索引。
    37. 说明【6】:
    38. 条件中尽量不用!=, Not in, Like, OR, NOT EXISTS 的条件语句。
    39. 示例【7】:
    40. select field3,field4 from tb where field2 is not null 不使用索引。
    41. 说明【7】:
    42. 空值不在索引中存储,所以上面语句执行不会使用索引检索。

    3.2 避免多表关联

    1. 1. 对单条记录检索时,请对 SQL 语句进行拆分,减少表关联。
    2. 示例:
    3. 改前
    4. SELECT Lot.LotSN
    5. FROM MO INNER JOIN
    6. Lot ON MO.MOId = Lot.MOId
    7. WHERE (MO.MOName = 'S20100408001-900G')
    8. 改后
    9. declare @MOId char(12)
    10. --先获取MOid
    11. SELECT @MOId = MOId
    12. FROM MO
    13. WHERE (MOName = 'S20100408001-900G')
    14. --单独查询Lot表,避免表关联
    15. SELECT Lot.LotSN
    16. FROM Lot
    17. WHERE (Lot.MOId = @MOId)
    18. 2. 利用表变量来替换大表关联,表变量的作用域为一个批处理,批处理完了,表变量也会
    19. 随之失效,比起临时表有它独特的优点:不用手动去删除表变量以释放内存。
    20. 示例:
    21. declare @t table
    22. (cardNo int)
    23. insert @t
    24. select cardNo from member where in('a-01',代理号二)
    25. select 字段 from order
    26. inner join @t on
    27. order.cardNo=@t.cardNo
    28. 3. 利用索引视图来提高大表关联的性能.

    3.3 临时表和表变量的灵活使用

    1. 表变量的好处:
    2. 1. 避免重编译:表标量可以避免临时表引起的重编译。
    3. 2. 没有事务日志开销:表变量不执行事务日志活动,临时表执行该活动。
    4. 3. 没有锁开销:表变量被看作局部变量,不错在临时表的锁开销。
    5. 4. 没有回滚开销:没有事务日志就不存在回滚事务。
    6. 临时表的好处:
    7. 1. 临时表空间一般利用虚拟内存,大大减少了硬盘的 I/O 次数,因此也提高了系统效率。
    8. 2. 事务完毕或会话完毕数据自动清空,不必记得用完后删除数据。
    9. 3. 数据当前会话期可见,其它的会话只能看到其结构,只能看到自己的数据,各会话的
    10. 数据互不干扰。

    3.5 防范死锁问题

    1. 1.一定要在 Delete 前加上 If Existed(select XID from youtable where 删除的条件), 判
    2. 断之后再进行删除。以减少表锁的机会
    3. 示例:
    4. If Exists(select LotId from Lot where LotSN = 'FG00000012')
    5. begin
    6. Delete Lot where LotSN = 'FG00000012'
    7. end
    8. 2. 地方一定要在自已写的存储过程前加上
    9. SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED –允许脏读
    10. 3. 客户化程序在 ADO.NET 编写时,数据库操作完成后,一定需要释放 connection 连
    11. 接对象,不要用全局的 connection 对象不释放。

    3.6 游标的谨慎使用

    1. (1) 尽管使用游标比较灵活,可以实现对数据集中单行数据的直接操作,但游标会在下
    2. 面几个方面影响系统的性能:
    3. 使用游标会导致页锁与表锁的增加
    4. 导致网络通信量的增加
    5. 增加了服务器处理相应指令的额外开销
    6. (2) 使用游标时的优化问题:
    7. 明确指出游标的用途:for read only 或 for update,在 for update 后指定被修改
    8. 的列。
    9. 示例:
    10. 定义一个标准游标:
    11. declare mycursor cursor for select * from yuangong
    12. 定义一个只读游标:
    13. declare mycursor cursor for select * from yuangong for read only
    14. 定义一个可写游标
    15. declare mycursor cursor for select * from yuangong for udpate of 列名

  • 相关阅读:
    JDictSelectTag 字典标签用法
    HIVE中替换UDF神器-- TRANSFORM()函数
    【附源码】Python计算机毕业设计球迷信息交流论坛
    GO 中的时间操作(time & dateparse)【GO 基础】
    主板知识:了解的PCI Express Gen 5的终极指南
    基于IDEA 工程项目的git实操
    求输入N段整数范围的素数之和。
    Sentinel:服务限流
    Spring 体系版本对应关系
    springboot二手书籍线上回收网站java ssm-0401u
  • 原文地址:https://blog.csdn.net/xdpcxq/article/details/128153557