成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么阿里要禁止使用存儲過程?

存儲
最近項目中遇到的存儲過程問題,讓我想起了去年出差時一位同事的發問:我覺得存儲過程挺好用的,為什么你不建議用?

之所以有這個題目,我既不是故意吸引眼球,也不想在本文對存儲過程進行教科書般論述。

[[406051]]

最近項目中遇到的存儲過程問題,讓我想起了去年出差時一位同事的發問:我覺得存儲過程挺好用的,為什么你不建議用?

當時我好似胸有萬言,但終究沒用一個實在的例子回答同事,只是從結論上大侃一通,代碼相對于 SQL,復用、擴展、通用性都要更強。想必同事并不信服。

現在想來,我最近正碰到的問題,算是一個可以回答同事的例子吧。

最近項目中有個新需求,需要校驗一個用戶是否有 Job,Certification,Disclosure 這三個業務數據。

翻看了代碼發現,系統的用戶個人頁面的 C# 代碼調用了三個存儲過程,去抓取用戶的 Job,Certification,Disclosure 數據。

我的新需求,自然需要復用這三個存儲過程,否則:若每一處都寫一次抓取數據的業務邏輯代碼,若業務邏輯發生變化,難以追查和維護所有讀取 Job,Certification,Disclosure 的 SQL。

如果我在 C# 代碼中調用這已有的三個存儲過程,事情本該非??炀湍芙Y束。我也是這么做的。

但 code reviewer 認為,我的需求中,并不需要 Job,Certification,Disclosure 這三個業務對象的數據。

我只是需要給定用戶是否有 Job,Certification,Disclosure 而已。

所以我應將是否有無 Job,Certification,Disclosure 的判斷邏輯寫在數據庫,最終通過網絡從數據庫傳到 web 服務器的僅是 true 或 false,節省網絡流量,這樣最好不過了。

也對。除開網絡性能,從接口設計的角度講,接口的傳入和返回值,都應是你本身需要的數據,不應帶有大量不需要或者需要 caller 去預處理的數據。

從接口語義表達就可知調用的目的,這樣代碼可讀性也會有大大提高。那就動手改。但沒想到的是問題來了。

為了講述問題,我簡化代碼,假設系統現有的存儲過程如下:

  1. CREATE PROCEDURE [dbo].[GetJobs] 
  2.     @PersonId int
  3.     @OrganizaitionId int 
  4.  ) 
  5. AS 
  6. BEGIN 
  7.   SELECT JobId,JobName,JobType FROM Job WHERE PersonId = @PersonId AND OrganizaitionId = @OrganizaitionId 
  8. END 

我在新的存儲過程中調用它,我需要獲得該 person 的 jobs 的數量,即 GetJobs 返回結果集的 count。

為了實現這一目的,首先想到的是使用臨時表,將返回結果集存入臨時表,再對其進行 count(*) 的計數操作:

  1. CREATE PROCEDURE [dbo].[MyProc] 
  2.     @PersonId int
  3.     @OrganizaitionId int
  4.  ) 
  5. AS 
  6. BEGIN 
  7.   CREATE TABLE #Temp
  8.     PersonId int
  9.     OrganizaitionId int 
  10.   ) 
  11.  
  12.   INSERT INTO #Temp EXEC dbo.GetJobs 
  13.     @PersonId = @PersonId, 
  14.     @ParentOrgId = @ParentOrgId 
  15.  
  16.   SELECT COUNT(*) FROM #Temp 
  17. END 

這種辦法簡單有效,但它存在嚴重的維護問題。未來如果被調用的存儲過程的返回結果集字段有變動,那么 MyProc 中的臨時表結構也需要隨之變化。這是令人難以接受的。

那么將 MyProc 中的 INSERT INTO 換為 SELECT INTO 呢?很遺憾,答案是不行。SQL 本身并不支持這種用法。

給現有存儲過程 GetJobs 加 output 參數?本例中因為 GetJobs 已被其他多處代碼或 SQL scripts 調用,所以對現有現有存儲過程進行改動會有不小風險。

我搜遍網絡,一位 MS MVP 的大神的文章幾乎總結了所有存儲過程之間傳遞數據的方法:How to Share Data between Stored Procedures。

他在文章中也無可奈何地說道:

Keep in mind that compared to languages such as C# and Java, Transact-SQL is poorly equipped for code reuse, why solutions in T?SQL to reuse code are clumsier.

最終我沒能找到一種滿意的辦法,無奈之下我在新寫的存儲過程中將查詢 Jobs 的語句寫一了次。

存儲過程在很多場景時有其優勢,比如性能,但對于業務邏輯的通用方法,非常不推薦將其寫在存儲過程中,代碼復用、擴展與客戶端語言比,相差甚遠。

也許終究能實現,但代價與風險比客戶端語言要高,得不償失。天知道還有沒有機會和那位前同事再討論這一話題呢。

作者:楊洋的圍脖啊

編輯:陶家龍

出處:segmentfault.com/a/1190000011138993

 

責任編輯:武曉燕 來源: Segmentfault
相關推薦

2022-02-22 12:51:39

存儲過程JavaSQL

2019-01-14 07:28:56

大數據云計算互聯網

2020-07-30 12:16:33

阿里巴巴Apache對象

2020-09-08 16:25:18

Apache BeancopyJava

2018-02-08 10:47:19

存儲技術列存儲

2019-11-13 14:38:34

Executors阿里線程池

2021-10-27 20:54:24

分庫分表高并發

2020-09-22 11:40:53

BigDecimalequalsJava

2025-04-17 08:47:23

2022-12-26 00:25:06

2022-06-30 08:03:13

Prisma數據庫工具開源

2015-05-25 15:31:56

C語言學習和使用 C 語言

2022-09-05 10:06:21

MySQL外循環內循環

2011-07-13 10:00:46

2015-08-06 10:14:15

造輪子facebook

2022-08-15 08:27:02

基站網絡

2013-03-12 14:30:09

Ubuntu操作系統

2025-05-16 02:00:00

HashMapJava代碼

2020-12-15 10:00:31

MySQL數據庫text

2020-09-14 09:47:56

Java開發類型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久伊人免费视频 | 一区二区三区av | 亚洲成人精品国产 | 精彩视频一区二区三区 | 亚洲国产午夜 | 日韩av免费在线电影 | 国产欧美在线播放 | se婷婷| 99tv| 91精品国产色综合久久不卡98 | 亚洲天堂成人在线视频 | 国产精品久久久久久久久久免费看 | 亚洲视频二区 | 国产一区二区三区网站 | 91久久国产综合久久 | 91精品一区二区三区久久久久 | 日本色婷婷| 国产一区二区三区在线视频 | 国产精品日日做人人爱 | 中文字幕一区在线 | 欧美成人a∨高清免费观看 色999日韩 | 亚洲精品在线播放 | 成人毛片视频免费 | 国产成人免费网站 | 精品欧美一区二区三区免费观看 | 日韩成人在线一区 | 一区二区三区视频在线观看 | 麻豆久久久久久久 | 久久伊人精品 | 99re在线视频观看 | 国产一区二区三区四区五区加勒比 | 99精品视频免费在线观看 | 日韩欧美国产精品一区二区三区 | 久久99这里只有精品 | 欧美成人第一页 | 午夜久久久久久久久久一区二区 | 羞羞视频网站 | 成年网站在线观看 | 不卡的av在线 | 日韩不卡视频在线 | 国产ts人妖另类 |