一種無奈因此另類的開發方式----SQL很強大!

很久沒寫點什麼了。。。sql

多年前。。。。。。

前些時間,與一多年前在北京共事過的略帶親戚關係的同事閒聊了會。數據庫

在北京那時,他們的主要是用Delphi語言,數據庫是MSSqlServer。服務器

他沒有大學學歷,甚至好像高中學歷都沒有,成長過程比較勵志,工廠流水線、理髮師、賣東西神馬的都幹過!!!性能

他是公司的主程,負責某行業管理軟件、呼叫中心等系統,最讓我佩服的,是他對MSSqlServer的熟悉程度,對我而言,膜拜之也並不過度。日誌

===============================================================================對象

現狀

聽他說,他們如今作B/S時,已經在用.Net了,多年前,也聽他們提過,說想轉到C#。blog

不過,當聊到開發方式時,我卻震驚了:由於對C#還不是很熟悉,因此,全部的CURD、全部的業務邏輯,統統用存儲過程來實現。C#沒有業務邏輯,各類數據操做都調用存儲過程來實現。索引

順便貼了一個存儲過程給我,只是一個刪數據的存儲過程。ip

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的他來講,這樣的開發方式耗時最短,性能最高。

簡單談下本身對這個的見解吧:

  優勢:

    一、對他來講,這多是最合適最快速的開發方式。

    二、在符合某些前提(如訪問量不大)的狀況,確實性能最高。

    三、一次操做只鏈接一次數據庫。

    四、直接操做數據,沒有轉換爲對象的操做,沒有生成SQL語句的操做。

    五、更改方便,只需改存儲過程,無需編譯發佈。

    六、大大減輕Web服務器的壓力(將就着算優勢吧)。

  缺點就太明顯了:

    一、只適合小項目。

 

    二、可讀性、可維護性、可擴展性。

    。。。。。。

  好吧,這兩點,足夠了。。。

Over~!~!~!

相關文章
相關標籤/搜索