翻譯|使用教程|編輯:鮑佳佳|2020-09-01 14:16:14.100|閱讀 288 次
概述:在本文中,我們將主要集中于對數據庫中的存儲過程進行單元測試,并舉例說明使用dbForge單元測試工具進行單元測試有多么簡單。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
dbForge Studio for SQL Server為有效的探索、分析SQL Server數據庫中的大型數據集提供全面的解決方案,并設計各種報表以幫助作出合理的決策。(為慶祝雙節來襲現dbForge Studio for SQL Server正版授權低至 1710元!包含多種授權方式供你選擇。)
點擊下載dbForge Studio for SQL Server最新試用版
單元測試是數據庫DevOps流程的重要組成部分。其主要目標是測試數據庫對象的組成部分,以便在項目早期發現任何故障或缺陷。這種方法使數據庫開發人員可以確保驗證他們所做的更改,并且項目將正常運行。在本文中,我們將主要集中于對數據庫中的存儲過程進行單元測試,并舉例說明使用dbForge單元測試工具進行單元測試有多么簡單。
之前,我們討論了為招聘服務創建SQL Server數據庫的過程。
圖1。招聘服務的數據庫架構
如上所示,數據庫包含以下實體:
但是,在系列文章中,我們以某種方式忽略了單元測試的關鍵方面。因此,現在,我建議我們仔細研究此方法,并通過為基于某些技能的員工搜索實現SearchEmployee存儲過程來舉例說明。為了確保數據完整性,我們應該在Skill表上添加唯一約束,如下所示:
ALTER TABLE [dbo].[Skill] ADD CONSTRAINT UniqueSkillName UNIQUE (SkillName);
但是,在執行此操作之前,請使用以下查詢確保SkillName字段中的數據不包含任何重復的條目:
SELECT [SkillName] FROM [JobEmpl].[dbo].[Skill] GROUP BY [SkillName] HAVING COUNT(*) > 1;
假設您有重復的條目,則需要將所有記錄標準化為SkillName字段相對于彼此的唯一值。
這一步驟中我們在技能名稱中創建了唯一性約束。現在,是時候實現SearchEmployee存儲過程了,如下所示:
CREATE PROCEDURE [dbo].[SearchEmployee] @SkillList NVARCHAR(MAX), @CountNotSkill INT = 1 AS BEGIN SET NOCOUNT ON; DECLARE @count_skills INT; SELECT [value] INTO #tbl_skill_tmp FROM STRING_SPLIT(@SkillList, N';'); SELECT s.[SkillID] ,s.[SkillName] INTO #tbl_skill FROM #tbl_skill_tmp AS tt INNER JOIN [dbo].[Skill] AS s ON s.[SkillName] = tt.[value]; SET @count_skills = (SELECT COUNT(*) FROM #tbl_skill); SELECT jh.* ,p.[ProjectName] ,p.[Description] AS [ProjectDescription] ,ts.* INTO #tbl_res0 FROM [dbo].[JobHistory] AS jh INNER JOIN [dbo].[Project] AS p ON p.[ProjectID] = jh.[ProjectID] INNER JOIN [dbo].[ProjectSkill] AS ps ON ps.[ProjectID] = p.[ProjectID] INNER JOIN #tbl_skill AS ts ON ps.[SkillID] = ts.[SkillID]; SELECT [EmployeeID] ,[SkillID] ,MIN([SkillName]) AS [SkillName] ,SUM(DATEDIFF(DAY, [StartDate], COALESCE([FinishDate], GETDATE()))) AS [Days] ,MIN([StartDate]) AS [StartDate] ,MAX(COALESCE([FinishDate], GETDATE())) AS [FinishDate] INTO #tbl_res FROM #tbl_res0 GROUP BY [SkillID] ,[EmployeeID]; SELECT emp.[EmployeeID] ,emp.[LastName] ,emp.[FirstName] ,r.[SkillID] ,r.[SkillName] ,r.[StartDate] ,r.[FinishDate] ,r.[Days] / 365 AS [Years] ,(r.[Days] - (r.[Days] / 365) * 365) / 30 AS [Months] ,r.[Days] - (r.[Days] / 365) * 365 - ((r.[Days] - (r.[Days] / 365) * 365) / 30) * 30 AS [Days] INTO #tbl_res2 FROM #tbl_res AS r INNER JOIN [dbo].[Employee] AS emp ON emp.[EmployeeID] = r.[EmployeeID]; SELECT [EmployeeID] ,[LastName] ,[FirstName] INTO #tbl_empl FROM #tbl_res2; SELECT ts.[SkillID] ,te.[EmployeeID] ,ts.[SkillName] ,te.[LastName] ,te.[FirstName] INTO #tbl_skill_empl FROM #tbl_skill AS ts CROSS JOIN #tbl_empl AS te; SELECT tse.[EmployeeID] ,tse.[LastName] ,tse.[FirstName] ,tse.[SkillID] ,tse.[SkillName] ,tr2.[StartDate] ,tr2.[FinishDate] ,tr2.[Years] ,tr2.[Months] ,tr2.[Days] INTO #tbl_res3 FROM #tbl_skill_empl AS tse LEFT OUTER JOIN #tbl_res2 AS tr2 ON tse.[SkillID] = tr2.[SkillID] AND tse.[EmployeeID] = tr2.[EmployeeID]; SELECT [EmployeeID] INTO #tbl_empl_res FROM (SELECT [EmployeeID] ,[SkillID] FROM #tbl_res3 WHERE [Months] >= 6 OR [Years]>=1 GROUP BY [EmployeeID] ,[SkillID]) AS t GROUP BY [EmployeeID] HAVING COUNT(*) >= @count_skills - @CountNotSkill; SELECT tr2.[EmployeeID], tr2.[LastName], tr2.[FirstName], tr2.[SkillID], tr2.[SkillName], tr2.[StartDate], tr2.[FinishDate], tr2.[Years], tr2.[Months], tr2.[Days] FROM #tbl_empl_res AS ter INNER JOIN #tbl_res2 AS tr2 ON ter.[EmployeeID] = tr2.[EmployeeID]; SELECT tr2.[EmployeeID], tr2.[LastName], tr2.[FirstName], tr0.[CompanyID], (SELECT TOP(1) com.[CompanyName] FROM [dbo].[Company] AS com WHERE com.[CompanyID]=tr0.[CompanyID]) AS [CompanyName], tr0.[PositionID], (SELECT TOP(1) p.[PositionName] FROM [dbo].[Position] AS p WHERE p.[PositionID]=tr0.[PositionID]) AS [PositionName], tr0.[ProjectID], tr0.[StartDate], tr0.[FinishDate], tr0.[Description], tr0.[ProjectName], tr0.[ProjectDescription], tr0.[SkillID], tr0.[SkillName], tr0.[Achievements], tr0.[ReasonsForLeavingTheProject], tr0.[ReasonsForLeavingTheCompany] FROM #tbl_res2 AS tr2 INNER JOIN #tbl_res0 AS tr0 ON tr0.[EmployeeID] = tr2.[EmployeeID] INNER JOIN #tbl_skill AS ts ON ts.[SkillID] = tr0.[SkillID]; DROP TABLE #tbl_skill_tmp; DROP TABLE #tbl_skill; DROP TABLE #tbl_res; DROP TABLE #tbl_res2; DROP TABLE #tbl_empl; DROP TABLE #tbl_skill_empl; DROP TABLE #tbl_res3; DROP TABLE #tbl_empl_res; DROP TABLE #tbl_res0; END GO
為什么不更詳細地檢查SearchEmployee存儲過程的工作?
對于初學者,它具有兩個輸入參數:
現在,讓我們轉到SearchEmployee存儲過程的主體:
完成上述步驟后,我們可以提取出能夠使用C#和T-SQL語言以及ASP.NET技術勝任的員工的姓名,但前提是最多只能缺少一種技能,如下所示:
EXEC [dbo].[SearchEmployee] @SkillList = N'C#;T-SQL;ASP.NET' ,@CountNotSkill = 1;
您可以在單元測試的幫助下涵蓋所創建解決方案的大部分甚至全部功能。最重要的是,單元測試是DevOps基本原理的一部分,因為它們在此自動化過程中扮演著關鍵角色之一。本次講解就這些,下一篇文章我們將講解如何創建并運行存儲過程 。立即下載體驗吧!點擊獲取正版授權!
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: