一种无奈所以另类的开发方式----SQL很强大!

好久没写点什么了。。。

多年前。。。。。。

前些时间,与一多年前在北京共事过的略带亲戚关系的同事闲聊了会。

在北京那时,他们的主要是用Delphi语言,数据库是MSSqlServer。

他没有大学学历,甚至好像高中学历都没有,成长过程比较励志,工厂流水线、理发师、卖东西神马的都干过!!!

他是公司的主程,负责某行业管理软件、呼叫中心等系统,最让我佩服的,是他对MSSqlServer的熟悉程度,对我而言,膜拜之也并不过分。

===============================================================================

现状

听他说,他们现在做B/S时,已经在用.Net了,多年前,也听他们提过,说想转到C#。

不过,当聊到开发方式时,我却震惊了:因为对C#还不是很熟悉,所以,所有的CURD、所有的业务逻辑,通通用存储过程来实现。C#没有业务逻辑,各种数据操作都调用存储过程来实现。

顺便贴了一个存储过程给我,只是一个删数据的存储过程。

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N‘[dbo].[up_DeleteTravelLineType]‘) AND type in (N‘P‘, N‘PC‘))
DROP PROCEDURE [dbo].[up_DeleteTravelLineType]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/* =============================================
-- Author:	 LSH
-- Create date: 2013-12-31
-- Description:	线路类型,(暂时不允许删除有线路的类型)当存在下属从表数据时,如果 @DeleteChild = 1 则删除下属信息,否则,返回 50005 错误码。
-- 调用示例
DECLARE @ErrCode int, @ReturnMsg nvarchar(256)
SET @=0;
EXEC @ErrCode = up_DeleteTravelLineType @Code = NULL, @DeleteChild = 0,
@Operator = ‘‘, @ReturnMsg = @ReturnMsg output, @Language = ‘简体中文‘
IF @ErrCode = 0
SELECT * FROM OperationLog WHERE LogType = ‘TravelLineType‘ AND KeyValue = @
ELSE
PRINT CONVERT(varchar(10), @ErrCode)+‘: ‘+
CASE @ErrCode
WHEN 0 THEN CASE @ReturnMsg WHEN 0 THEN ‘数据无变化‘ ELSE @ReturnMsg+‘ 行数据受影响‘ END
WHEN 50001 THEN @ReturnMsg+‘ 不能为空‘                         [email protected] 输出对应的参数名称(不带 @ 符号)。
WHEN 50002 THEN @ReturnMsg+‘ 已存在‘                           [email protected] 输出不能重复的值。
WHEN 50003 THEN ‘Code ‘[email protected]+‘ 不存在‘                   [email protected] 输出主键对应的参数值。
WHEN 50004 THEN @ReturnMsg+‘ 指定了无效值‘                     [email protected] 输出对应的参数名称(不带 @ 符号)。
WHEN 50005 THEN ‘当前数据下包含至少一个 ‘[email protected]           [email protected] 输出对应的子数据表名。
WHEN 50006 THEN @ReturnMsg+‘ 引用了不存在的主表数据‘           [email protected] 输出对应的参数名称(不带 @ 符号)。
WHEN 50007 THEN ‘ 数据在上次加载后已被修改,修改时间为: ‘[email protected] -- @ReturnMsg 输出最后的修改日期。
WHEN 50008 THEN @ReturnMsg+‘ 需要使用当前数据‘                 [email protected] 输出对应的引用数据表名。
WHEN 51000 THEN @ReturnMsg+‘ 不是有效的操作员‘                 [email protected] 输出操作员参数的值。
ELSE @ReturnMsg+‘ 可尝试查看 SELECT * FROM ErrorLog 中的信息‘
END
-- ============================================= */
CREATE PROCEDURE [dbo].[up_DeleteTravelLineType]
(
@Code [varchar](20),
@DeleteChild [bit] = 0,
@Operator [nvarchar](32) = NULL,   -- 操作员
@ReturnMsg [nvarchar](256) = NULL OUTPUT,
@Language [sysname] = NULL        -- 语言,如: ‘简体中文‘,‘us_english‘ 等,NULL 或 ‘‘ 时使用当前语言。
)
AS
BEGIN
-- 对存储过程做一些基本设置
SET NOCOUNT ON; -- 不返回计数(表示受 Transact-SQL 语句影响的行数)。
IF @Language <> ‘‘ SET LANGUAGE @Language;	-- 设置语言
IF @Operator = ‘‘ SET @Operator = NULL;

-- 暂时不启用删除子数据功能,如果启用该功能,需要处理好子数据又有子数据的情况!!!
SET @DeleteChild = 0; 

-- 判断参数合法性,用 FORMATMESSAGE() 设置错误信息。
IF @Code IS NULL
BEGIN
SET @ReturnMsg = ‘Code‘
RETURN 50001
END;

DECLARE @ErrCode int
SELECT @ErrCode = 0, @ReturnMsg=‘‘
IF NOT EXISTS(SELECT * FROM TravelLineType WHERE Code = @Code)-- 判断数据是否存在
SELECT @ErrCode = 50003, @ReturnMsg = ISNULL(CONVERT(varchar(128),@Code),‘null‘)
ELSE
IF dbo.uf_ExistsUserCode(@Operator) = 0 -- dbo.uf_ExistsUser(@Operator) = 0
SELECT @ErrCode = 51000, @ReturnMsg = ISNULL(@Operator, ‘null‘)
ELSE -- 如果有从表数据时,对从表数据进行检查,暂时不允许删除有航线的类型
IF ((@DeleteChild IS NULL) OR (@DeleteChild = 0))
AND (EXISTS(SELECT * FROM TravelLine WHERE TypeCode = @Code))
SELECT @ErrCode = 50005, @ReturnMsg = ‘TravelLine‘
ELSE
-- ============================================= */
CREATE PROCEDURE [dbo].[up_DeleteTravelLineType]
(
@Code [varchar](20),
@DeleteChild [bit] = 0,
@Operator [nvarchar](32) = NULL,   -- 操作员
@ReturnMsg [nvarchar](256) = NULL OUTPUT,
@Language [sysname] = NULL        -- 语言,如: ‘简体中文‘,‘us_english‘ 等,NULL 或 ‘‘ 时使用当前语言。
)
AS
BEGIN
-- 对存储过程做一些基本设置
SET NOCOUNT ON; -- 不返回计数(表示受 Transact-SQL 语句影响的行数)。
IF @Language <> ‘‘ SET LANGUAGE @Language;	-- 设置语言
IF @Operator = ‘‘ SET @Operator = NULL;

-- 暂时不启用删除子数据功能,如果启用该功能,需要处理好子数据又有子数据的情况!!!
SET @DeleteChild = 0; 

-- 判断参数合法性,用 FORMATMESSAGE() 设置错误信息。
IF @Code IS NULL
BEGIN
SET @ReturnMsg = ‘Code‘
RETURN 50001
END;

DECLARE @ErrCode int
SELECT @ErrCode = 0, @ReturnMsg=‘‘
IF NOT EXISTS(SELECT * FROM TravelLineType WHERE Code = @Code)-- 判断数据是否存在
SELECT @ErrCode = 50003, @ReturnMsg = ISNULL(CONVERT(varchar(128),@Code),‘null‘)
ELSE
IF dbo.uf_ExistsUserCode(@Operator) = 0 -- dbo.uf_ExistsUser(@Operator) = 0
SELECT @ErrCode = 51000, @ReturnMsg = ISNULL(@Operator, ‘null‘)
ELSE -- 如果有从表数据时,对从表数据进行检查,暂时不允许删除有航线的类型
IF ((@DeleteChild IS NULL) OR (@DeleteChild = 0))
AND (EXISTS(SELECT * FROM TravelLine WHERE TypeCode = @Code))
SELECT @ErrCode = 50005, @ReturnMsg = ‘TravelLine‘
ELSE
DELETE FROM TravelLineType WHERE Code = @Code

-- 备份数据
DECLARE @BackupID int; SET @BackupID = 0;
EXEC @ErrCode = up_BackupData @DataFlag = ‘TravelLineType‘, @DataKey = @Code,
@DataContent = @DataContent, @BackupID = @BackupID OUTPUT
IF @ErrCode = 0
BEGIN
SET @LogText = @LogText + ‘数据已备份,备份标识: ‘+CONVERT(varchar, @BackupID)
-- 记录操作日志
EXEC @ErrCode = up_LogOperation @LogType = ‘TravelLineType‘, @KeyValue = @Code, @Operate=‘删除‘,
@[email protected], @[email protected], @Description=‘‘, @LogID = @LogID OUTPUT
END;
IF @ErrCode = 0
BEGIN
IF @TranCounter = 0
COMMIT TRANSACTION
END
ELSE
BEGIN
IF @TranCounter = 0
ROLLBACK TRANSACTION
ELSE
ROLLBACK TRANSACTION ProcTRAN
END
END TRY
BEGIN CATCH
SELECT @ErrCode = ERROR_NUMBER(), @ReturnMsg = ERROR_MESSAGE()

IF (XACT_STATE() = -1) OR (@TranCounter = 0)
BEGIN
ROLLBACK TRANSACTION;
IF @TranCounter > 0
BEGIN TRANSACTION
END
ELSE
ROLLBACK TRANSACTION ProcTRAN 

-- 记录错误日志
IF @ErrCode < 50000
EXEC dbo.up_LogError;
END CATCH

RETURN @ErrCode; -- 设置返回值

END;
GO

EXEC dp_SetDescription N‘删除线路类型,(暂时不允许删除有线路的类型)当存在下属从表数据时,如果 @DeleteChild = 1 则删除下属信息,否则,返回 50005 错误码。‘, ‘PROCEDURE‘, ‘up_DeleteTravelLineType‘
GO
EXEC dp_SetDescription N‘指定要删除的数据主键。‘, ‘PROCEDURE‘, ‘up_DeleteTravelLineType‘, ‘PARAMETER‘, ‘@Code‘
GO
EXEC dp_SetDescription N‘暂未启用!当存在下属从表数据时,如果 @DeleteChild = 1 则删除下属信息,否则,返回 50005 错误码。‘, ‘PROCEDURE‘, ‘up_DeleteTravelLineType‘, ‘PARAMETER‘, ‘@DeleteChild‘
GO

  好吧,虽然自己简历上也写着熟悉MSSqlServer(存储过程、触发器、视图、游标、索引),但看到这存储过程,真心能感受到差距。。。

看法不一致

虽然佩服他的Sql,但我并不推崇这种开发方式,甚至抵触。

但他们也是无奈,要实现功能,对C#又不太熟,对精通SQL的他来说,这样的开发方式耗时最短,性能最高。

简单谈下自己对这个的看法吧:

  优点:

    1、对他来说,这可能是最合适最快速的开发方式。

    2、在符合某些前提(如访问量不大)的情况,确实性能最高。

    3、一次操作只连接一次数据库。

    4、直接操作数据,没有转换为对象的操作,没有生成SQL语句的操作。

    5、更改方便,只需改存储过程,无需编译发布。

    6、大大减轻Web服务器的压力(将就着算优点吧)。

  缺点就太明显了:

    1、只适合小项目。

    2、可读性、可维护性、可扩展性。

    。。。。。。

  好吧,这两点,足够了。。。

Over~!~!~!

  

一种无奈所以另类的开发方式----SQL很强大!

时间: 2024-10-13 04:35:36

一种无奈所以另类的开发方式----SQL很强大!的相关文章

DBA 需要知道N种对数据库性能的监控SQL语句

--DBA 需要知道N种对数据库性能的监控SQL语句 -- IO问题的SQL内部分析 下面的DMV查询可以来检查当前所有的等待累积值. Select wait_type, waiting_tasks_count, wait_time_ms from sys.dm_os_wait_stats where wait_type like 'PAGEIOLATCH%' order by wait_type --可以通过运行下面的查询得到每个文件的信息,了解哪个文件经常要做读(num_of_reads/

php连接mysql的三种方式和预处理下的sql注入

0x00 前言 学习了一下堆叠注入和这三种连接方式预处理下的SQL注入问题. 0x01 基础知识 参考: https://www.cnblogs.com/joshua317/articles/5989781.html https://www.cnblogs.com/geaozhang/p/9891338.html 1.即时 SQL 一条 SQL 在 DB 接收到最终执行完毕返回,大致的过程如下: 1. 词法和语义解析: 2. 优化 SQL 语句,制定执行计划: 3. 执行并返回结果: 如上,一条

看别人写的优秀代码,是对自己的一种提高,看别人写的很恶心的代码,对自己也是一种提高:告诉自己不要这样写(转)

这两天,我做了两件事: 1.重构了系统某个模块的部分代码: 花了一天时间,一个6k多行的java文件,搞到4k行加若干个类文件,恕我能力有限,后面的实在重构不下去了,那是一种3个domain属性名几乎一样100多个字段但是却用同一个copy了三遍的方法来处理的欲哭无泪,那是一种使劲滚鼠标滚轮都滚不到一个方法尾部的绝望(100多个字段的几个类属性equals来,equals去,get来,set去的,这样类型的方法有那么五六个,你说能不多吗)...... 2.做了一个日志处理的小工具: 客户要求把日

三种数据库日期转字符串对照sql server、oracle、mysql(V4.11)

三种数据库日期转换对照: http://blog.csdn.net/zljjava/article/details/17552741 SQL类型转换函数:cast(type1 as type2) 数据库中的日期类型 SQL SERVER DATE 1970-01-01 DATETIME 1970-01-01 00:00:00 Oracle DATE 2015-08-07 17:34:37 TIMESTAMP 1970-01-01 00:00:00.000000 是DATE的扩展类型,多了小数秒

Mybatis传多个参数(三种解决方案) mapper.xml的sql语句修改!

第一种 Public User selectUser(String name,String area); 对应的Mapper.xml <select id="selectUser" resultMap="BaseResultMap"> select * from user_user_t where user_name = #{0} and user_area=#{1} </select> 其中,#{0}代表接收的是dao层中的第一个参数,#{

T4模板~又名基架---一种提升ASP.NET MVC开发速度的强大工具!

看过的相当不错的一篇文章,但是对基架还时不太理解,大神们看到,希望指点一二,能告诉点学习资源就更好了! 本篇文章不是出自本人之手,转载完全处于膜拜以及学习! 欢迎加我微信:jkxx123321 备注博客加就可以了! 最近由于需要在框架中提供一些自定义模板的功能,找到了一篇博客,可惜似乎是翻译工具直接翻的,读不通顺,就试着自己翻译下,我不会完全翻译原文的句子,可能会对原文进行小范围的我认为更合适的句子并添加些注释,,原文地址如下: http://blogs.msdn.com/b/webdev/ar

1001种玩法 | Python Prompt Toolkit:构建强大交互式命令行的 Python 工具库

Python Prompt Toolkit:构建强大交互式命令行的 Python 工具库 prompt_toolkit 是一个用于构建强大交互式命令行的 Python 工具库. 你是不是在找交互式的 Python shell 工具 ptpython 呢?我们把 ptpython 的源码转移到了一个独立的仓库.如此一来,我们确信  prompt_toolkit 库不会被其他 ptpython 东西"污染",并且 ptpython 也可以独立开发.现在必须用下面这个命令安装 ptpytho

T-SQL动态查询(4)——动态SQL

接上文:T-SQL动态查询(3)--静态SQL 前言: 前面说了很多关于动态查询的内容,本文将介绍使用动态SQL解决动态查询的一些方法. 为什么使用动态SQL: 在很多项目中,动态SQL被广泛使用甚至滥用,很多时候,动态SQL又确实是解决很多需求的首选方法.但是如果不合理地使用,会导致性能问题及无法维护.动态SQL尤其自己的优缺点,是否使用需要进行评估分析: 动态SQL优点: 动态SQL提供了强大的扩展功能,能够应付复杂的需求,即使在需求增加时也能应对,并且不会因为需求的增加而导致代码的线性增长

Hadoop每日一讨论整理版

这是我在几个QQ群发起的Hadoop每日一讨论小活动,每天中午2点左右发出一个关于Hadoop的知识片段,在此做一个整理. [每日一讨论]之计算框架(2013-5-21) 就计算框架而言,Hadoop目前比较成熟的只有离线计算框架MapReduce(通常运行时间在1min以上),以及构建在MapReduce之上支持sql的Hive.随着发展,实时计算(通常运行时间在0~5s)有了需求,于是诞生了仿照Google dremel实现的Apache Drill和Cloduera impala,Twit