惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
Last Week in AI
Last Week in AI
S
SegmentFault 最新的问题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学
The Cloudflare Blog
IT之家
IT之家
雷峰网
雷峰网
小众软件
小众软件
博客园 - 叶小钗
博客园 - 聂微东
爱范儿
爱范儿
博客园 - 司徒正美
博客园 - 三生石上(FineUI控件)
V
Visual Studio Blog
博客园 - 【当耐特】
V
V2EX
博客园_首页
T
Tailwind CSS Blog

博客园 - 秋雨飘飘

显示日期的javascript日历 Iframe的基础应用——关于Iframe刷页问题的两种方法 关于left join的讨论 往表中允许为null的字段插入null值 - 秋雨飘飘 - 博客园 sql查询最大最小值 SQL Server CHARINDEX和PATINDEX详解 sql行列转换 sql语句优化的一些测试函数 存储过程的作用是自动生成编号 数据库管理常用SQL SQL Server 中多行多列连接成为单行单列 T-SQL 编程规范和优化技巧 (转)SQL Server 索引结构及其使用 动态查询SQL中变量的返回值 求薪水第三高的雇员的SQL题(图解) 表连接的比较left join/right join/inner join sql 视图 sql 日期函数之对于周的处理 如何提升checkbox的用户体验
存储过程的编写经验
秋雨飘飘 · 2007-07-11 · via 博客园 - 秋雨飘飘

1.       结构

if exists (

 select * from sysobjects

 where id = object_id(N'[dbo].[np_DailyClose]')

    and OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[np_DailyClose]

GO

/****************************************************

       过程名称:np_DailyClose

       目的: 日结处理, 每日停业后必须做此工作,且只能做一次

       创建日期:             作者      
修改日期:                 修改人:                 内容:为采购退货暂估回冲单独增加处理程序

 返回代码:

    -1 该日期已经做过日结

    0 成功返回

 涉及表:

 1. tConfig

 讨论:

 1

 2

*****************************************************/

CREATE proc np_DailyClose (

 @dTransDate datetime -- 业务日期

)

as

return -- np_DailyClose

  

1.       结果的三种获得方法:可带回值的参数,return 值,select 返回记录集

2.       编写过程

1) 参数

2) 设置环境:显示设置一些环境开关:如加锁方法、set nocount on 等,否则因为用户环境不同,影响运行效果。

3) 框架:构思结构

4) 变量:统一放在前面,并注释。

5) 注释:注释和代码同步完成,保持一致。

6) 编写

7) 讨论记录

8) 测试

3.       必须考虑的问题

3.1     可读性

1) 逻辑清晰

2) 语句不要过于复杂,靠产生临时表过渡

3) 注释

4) 一屏可视,便于思考

5) 艺术感

3.2     效率

一种方法和语句的使用,必须考虑它的执行效率。注意以下问题:

1) 回避not in查询

2) 游标嵌套慎用

3) 使用索引:善于用索引,大大提高速度,在语句中有时需要显式说明。

4) 事务嵌套慎用。

结存程序一般30分钟以上,主要原因就是使用了not in 查询、游标嵌套、没有用索引。改造后同样数据量9秒就能完成。

4.       事务

1) 保持一致性所必需,必须有意识的考虑何时必须用事务。

2) 注意加锁特性,加锁属性开关状态。辽阳的例子,informix缺省加锁返回机制没有注意,造成偶尔死机,问题非常隐蔽。

3) 处理不当会带来系统死锁。

4) 仔细测试,否则的灾难将难以挽回。

5) 大量语句的事务推荐方法,将存储过程嵌在事务中,这样可以防止意外出错,造成死锁。见附件1

5.       测试

5.1     测试环境的搭建,要保存一个对应的程序,因为不会轻易结束。见附件3

5.2     编写和测试花一样的时间。

5.3     任何改动,都要测试。

5.4     叫真,不要想当然,因为还有系统软件的问题。如,错误号状态,是最后一个语句的错误,Sql 7.0bug : 语句“if @@Error <> 0,永远得不到想象的结果。

5.5     调式工具

1.       了解表的连接原理,能力进阶的关键

1)  灵活性,左连接,右连接。。。

2)  查询效率,条件语句的写法和顺序,自己掌握优化的主动权。

3)  保证正确,如update from累加修改时

       
update tMembers 

                     
set 

                            iShareA  
= a.iShareA + b.iNewShare 

                     
from vMembers a, (select * from vMembers) b

                     
where a.iMemberID = b.iUpMemberID 



       
update tMembers 

                     
set 

                            iShareA  
= a.iShareA + b.iNewShare 

                     
from tMembers a, (select * from vMembers) b

                     
where a.iMemberID = b.iUpMemberID 

区别:

使用视图时,左侧iShareA 和 右侧a.iShareA不是同一条记录;使用表时是一条。

iShareA  
= a.iShareA + b.iNewShare

2.       一些经验

2.1     善用临时表

1)避免多用户重名冲突。

2)  速度快,内存表。

3)  简化逻辑

4)  数据重用

2.2     回避not in 的技巧

  
--打标记bMark = 1(下一步对bMark = 0 的进行插入,这样速度快得多)

  
update #tWIV_Total set bMark = 1 

  
from

    #tWIV_Total a, tTWAccount b

  
where

    a.cWhsID 
= b.cWhsID  and a.cItemID = b.cItemID and a.cVendorID = b.cVendorID

 

  
-- 3)将bMark = 0 的关键字插入到tTWAccount中

  
insert into tTWAccount (cWhsID, cItemID, cVendorID, cCtrGrpID)  

  
select

    cWhsID,

    cItemID,

    cVendorID,

    
'' -- because not null 

  
from

    #tWIV_Total 

  
where

    bMark 
= 0

2.3     浮点数慎用

1)  会有芯片运算影响等问题

2)  累计求和时,舍入误差,经常产生“1分钱问题”。

3)  运行中产生意外结果,如判断 = 0,本来是0,可能判断结果不为0

2.4     统计数字作分母时,注意筛选条件加上<> 0限制,如

                     
select iLevel, count(*) iCount 

                            
into #tChainLevelCount

                            
from tMembers a, tChainLevel b

                            
where 

                                   a.iLevel 
= b.iID

                                   
and a.cState = '0' and b.cType = 'A' 

                            
group by iLevel

                            
having count(*> 0