一種無奈所以另類的開發方式----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+' 不能為空'                         --@ReturnMsg 輸出對應的參數名稱(不帶 @ 符號)。
WHEN 50002 THEN @ReturnMsg+' 已存在'                           --@ReturnMsg 輸出不能重復的值。
WHEN 50003 THEN 'Code '+@ReturnMsg+' 不存在'                   --@ReturnMsg 輸出主鍵對應的參數值。
WHEN 50004 THEN @ReturnMsg+' 指定了無效值'                     --@ReturnMsg 輸出對應的參數名稱(不帶 @ 符號)。
WHEN 50005 THEN '當前數據下包含至少一個 '+@ReturnMsg           --@ReturnMsg 輸出對應的子數據表名。
WHEN 50006 THEN @ReturnMsg+' 引用了不存在的主表數據'           --@ReturnMsg 輸出對應的參數名稱(不帶 @ 符號)。
WHEN 50007 THEN ' 數據在上次加載后已被修改,修改時間為: '+@ReturnMsg -- @ReturnMsg 輸出最后的修改日期。
WHEN 50008 THEN @ReturnMsg+' 需要使用當前數據'                 --@ReturnMsg 輸出對應的引用數據表名。
WHEN 51000 THEN @ReturnMsg+' 不是有效的操作員'                 --@ReturnMsg 輸出操作員參數的值。
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='刪除', 
@Operator=@Operator, @Detail=@LogText, @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~!~!~!

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM