SQL 框架






4.72/5 (22投票s)
框架使应用程序以更有条理、更高效的方式进行编码。它有助于新分配的开发人员在短时间内理解代码结构。对于大型应用程序来说,它是必不可少的。
引言
经历过大型应用程序开发的开发人员知道框架的必要性。在这方面,像团队负责人、技术负责人和项目经理(直至首席技术官)这样的更有经验的开发人员非常尊重它。他们从经验中知道,大型应用程序应该以非常有条理的方式开发,以便新分配的开发人员只需很短的时间就能掌握应用程序背后的开发结构,并为团队负责人或其他高级开发人员节省更多成本。他们也知道,在应用程序的开发完成后,维护将变得简单且经济高效。
背景
除此之外,我将着手开发一个 SQL 框架。我将通过演示来展示其必要性。
开始吧
- 打开 SQL Management Studio
我想首先在 SQL Management Studio 中设计一个表结构,如下所示
假设您在一个大型软件公司为一个大型项目工作,并且这个项目将花费很长时间。您在这个项目中有许多程序员在您手下工作。有时,程序员会离开您的软件公司,并被新程序员取代。到目前为止,这是一个大型项目,因此底层数据库的大小也会相应增大。假设您分配了一个任务给一个程序员,要求他创建一个带有适当验证和其他必要命令的存储过程来进行数据插入。
下面的过程是由程序员根据他分配的任务创建的。
CREATE PROCEDURE [dbo].[Customer_Set]
@Name as varchar(50),
@Address as varchar(250),
@Mobile as varchar(50)
AS
BEGIN
SET NOCOUNT ON
--Validation
IF @Name IS NULL
BEGIN
RAISERROR ('Name cannot be empty.',16,1)
END
IF LEN(@Name)<3
BEGIN
RAISERROR ('Name cannot be less than 3 characters.',16,1)
END
--Data Insertion
BEGIN TRY
INSERT INTO [dbo].[Customer]
([Name]
,[Address]
,[Mobile])
VALUES
(@Name
,@Address
,@Mobile)
END TRY
BEGIN CATCH
RETURN (0)
END CATCH
RETURN (1)
END
您还分配了另一位开发人员来编写供应商表的存储过程。
然后像下面这样编写存储过程
CREATE PROCEDURE [dbo].[Supplier_Set]
@Name as varchar(50),
@Address as varchar(250),
@Mobile as varchar(50)
AS
BEGIN
SET NOCOUNT ON
--Validation
IF @Name IS NULL
BEGIN
RAISERROR ('Please enter supplier name.',16,1)
END
IF LEN(@Name)<3
BEGIN
RAISERROR ('Supplier name cannot be less than 3 characters.',16,1)
END
--Data Insertion
BEGIN TRY
INSERT INTO [dbo].[Supplier]
([Name]
,[Address]
,[Mobile])
VALUES
(@Name
,@Address
,@Mobile)
END TRY
BEGIN CATCH
RETURN (-1)
END CATCH
RETURN (1)
END
在审查上面两位程序员编写的两个存储过程的代码时,您会发现以下差异
IF @Name IS NULL
BEGIN
RAISERROR ('Name cannot be empty.',16,1)
END
IF LEN(@Name)<3
BEGIN
RAISERROR ('Name cannot be less than 3 characters.',16,1)
END
BEGIN CATCH
RETURN (0)
END CATCH
RETURN (1)
另一位程序员
IF @Name IS NULL
BEGIN
RAISERROR ('Please enter supplier name.',16,1)
END
IF LEN(@Name)<3
BEGIN
RAISERROR ('Supplier name cannot be less than 3 characters.',16,1)
END
BEGIN CATCH
RETURN (-1)
END CATCH
RETURN (1)
所以一位程序员写道
- 名称不能为空
- 名称不能少于 3 个字符
- RETURN (0)
另一位程序员写道
- 请输入供应商名称
- 供应商名称不能少于 3 个字符
- RETURN (-1)
对于相同类型的工作,他们没有使用相似的消息,并且他们还返回了 0 和 -1,这些是不易理解的。其他开发人员可能会写其他内容。所以这个系统不是一个通用的系统,也不是遵循相同的结构。
如果有很多由许多开发人员编写的上述存储过程,管理起来将非常困难。
系统应该遵循我称之为框架的结构进行开发,并且所有消息都应该有一个通用的、可读的返回类型,以及关于结构的、通用的其他内容。这将帮助我们轻松地管理系统,并付出更少的努力。
在这种情况下,我们可以通过编写一些额外的存储过程来构建一个框架,并且可以根据您的需求进行扩展,以构建您自己的框架。
让我们创建一个存储过程来设置一些常量变量,最有可能像 .NET 中的 Enum
。这些常量实际上将在其他常规过程中用于不同的操作类型。这些常量用于通用的系统开发。
CREATE PROCEDURE [dbo].[GetValidationConstraint]
--Output values
@EmptyCheck int OUTPUT,
@LenCheck int =NULL OUTPUT,
@NoDataExist int =NULL OUTPUT,
@True bit =NULL OUTPUT,
@False bit =NULL OUTPUT
AS
BEGIN
SELECT @EmptyCheck=1
SELECT @LenCheck =2
SELECT @NoDataExist =3
SELECT @True=1
SELECT @False=0
END
另一个过程是为整个应用程序提供通用的返回消息。
CREATE PROCEDURE [dbo].[ReturnMessage]
--Success, Fail is the order of output parameter
@Success int OUTPUT,
@Fail int OUTPUT
AS
SET NOCOUNT ON
BEGIN
SELECT @Fail=0
SELECT @Success=1
END
下面的过程是为应用程序提供通用消息的
CREATE PROCEDURE [dbo].[MessageHelper]
--Input values
@Field varchar(200) =NULL,
@MinLenght int =NULL,
@ValidationConstraint int,
--Output values
@ValidationMessage varchar(200) OUTPUT
AS
BEGIN
--Variables
DECLARE @EMPTY_MESSAGE varchar(50),
@MINIMUM_LENGHT_MESSAGE varchar(50),
@NO_DATA_EXIST_MESSAGE varchar(50)
DECLARE @EMPTY int,
@LEN int,
@NO_DATA_EXIST int
DECLARE @SUCCESSED int,
@FAILED int
--Message Constraint
SET @EMPTY_MESSAGE = 'cannot be empty.'
SET @MINIMUM_LENGHT_MESSAGE ='cannot be less than'
SET @NO_DATA_EXIST_MESSAGE = 'No record found.'
--Get global values
EXEC ReturnMessage @SUCCESSED output, @FAILED output
EXEC GetValidationConstraint @EMPTY OUTPUT, @LEN OUTPUT, @NO_DATA_EXIST OUTPUT
--Set message
IF @ValidationConstraint = @EMPTY
BEGIN
IF LEN(@Field)<=0
BEGIN
RAISERROR('Field name cannot be empty. _
StoreProcedure/MessageHelper',16,1)
RETURN @FAILED
END
SELECT @ValidationMessage = @Field + ' ' + @EMPTY_MESSAGE
END
IF @ValidationConstraint = @LEN
BEGIN
IF @MinLenght IS NULL OR @MinLenght <=0
BEGIN
RAISERROR('Minimum length cannot be empty. _
StoreProcedure/MessageHelper',16,1)
RETURN @FAILED
END
ELSE
BEGIN
SELECT @ValidationMessage = @Field + ' ' + _
@MINIMUM_LENGHT_MESSAGE + ' ' + CONVERT(varchar, @MinLenght)
END
END
IF @ValidationConstraint = @NO_DATA_EXIST
BEGIN
SELECT @ValidationMessage = @NO_DATA_EXIST_MESSAGE
END
END
编写您的存储过程以将数据 insert
到 Customer
表中
CREATE PROCEDURE [dbo].[Customer_Set]
--Input values
@Name as varchar(50),
@Address as varchar(250),
@Mobile as varchar(50),
--Output values
@LASTID bigint OUTPUT,
@MESSAGE varchar(200) =NULL OUTPUT
AS
SET NOCOUNT ON
BEGIN
--Constraint Variables For Readable Return Value
DECLARE @SUCCESSED int,
@FAILED int
--Constraint Variables For Readable Validation Operation
DECLARE @EMPTY int,
@LEN int
BEGIN TRY
--Get constraint value for success and failed
EXEC ReturnMessage @SUCCESSED output, @FAILED output
--Get constraint value for validation. @EMPTY is for empty check
--and @LEN is for length check common messaging system.
EXEC GetValidationConstraint @EMPTY output, @LEN output
--Validation
IF LEN(@Name)=0
BEGIN
EXEC MessageHelper 'Name', @EMPTY,@MESSAGE OUTPUT
--It will generate a common empty message.
RETURN @FAILED-- Readable Failed Return
END
IF LEN(@Name)<3
BEGIN
EXEC MessageHelper 'Name',3, @LEN,@MESSAGE OUTPUT
--It will generate a common length check message.
RETURN @FAILED-- Readable Failed Return
END
--Data insertion
INSERT INTO [dbo].[Customer]
([Name]
,[Address]
,[Mobile])
VALUES
(@Name
,@Address
,@Mobile)
SELECT @LASTID=SCOPE_IDENTITY()
END TRY
BEGIN CATCH -- Error Trapping Section
DECLARE @ErrorMessage nvarchar(4000);
DECLARE @ErrorSeverity int;
DECLARE @ErrorState int;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState);
RETURN @FAILED -- Readable Failed Return
END CATCH
RETURN @SUCCESSED -- Readable Success Return
END
通过上述方式,系统中的所有消息都将保持通用。现在编写用于从 Customer
表中获取所有记录的存储过程。
CREATE PROCEDURE [dbo].[Customer_Get]
--Output values
@TOTAL_ROWS bigint OUTPUT,
@MESSAGE varchar(200) =NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON
--Variables
DECLARE @SUCCESSED int,
@FAILED int
DECLARE @EMPTY int,
@LEN int,
@NO_DATA_EXIST int
BEGIN TRY
--Get constraint value
EXEC ReturnMessage @SUCCESSED OUTPUT, @FAILED OUTPUT
EXEC GetValidationConstraint @EMPTY OUTPUT, _
@LEN OUTPUT,@NO_DATA_EXIST OUTPUT
--Validation
IF (SELECT COUNT(CustomerId) FROM Customer )<= 0
BEGIN
EXEC MessageHelper '', @NO_DATA_EXIST,@MESSAGE OUTPUT
--It will generate common no data exist message.
SELECT @TOTAL_ROWS=0
RETURN @SUCCESSED
END
--Data retrieval
SELECT [CustomerId]
,[Name]
,[Address]
,[Mobile]
FROM [dbo].[Customer]
--Get total rows
SELECT @TOTAL_ROWS=@@ROWCOUNT
END TRY
BEGIN CATCH
DECLARE @ErrorMessage nvarchar(4000);
DECLARE @ErrorSeverity int;
DECLARE @ErrorState int;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState);
RETURN @FAILED
END CATCH
RETURN @SUCCESSED
END
编写用于从 Customer
表中 delete
记录的存储过程
CREATE PROCEDURE [dbo].[Customer_DeleteById]
--Input values
@CustomerId bigint,
@MESSAGE varchar(200) =NULL OUTPUT
AS
BEGIN
--Variables
DECLARE @SUCCESSED int,
@FAILED int
DECLARE @EMPTY int,
@LEN int
BEGIN TRY
--Get constraint value
EXEC ReturnMessage @SUCCESSED OUTPUT, @FAILED OUTPUT
EXEC GetValidationConstraint @EMPTY OUTPUT, @LEN OUTPUT
--Validation
IF @@CustomerId <=0
BEGIN
EXEC MessageHelper 'Customer Id', @EMPTY,@MESSAGE OUTPUT
RETURN @FAILED
END
--Data deletion
DELETE FROM [dbo].[Customer]
WHERE (CustomerId = @CustomerId)
END TRY
BEGIN CATCH
DECLARE @ErrorMessage nvarchar(4000);
DECLARE @ErrorSeverity int;
DECLARE @ErrorState int;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState);
RETURN @FAILED
END CATCH
RETURN @SUCCESSED
END
因此,通过一些额外的存储过程,我们可以为 Web 或软件应用程序构建一个通用的消息传递和验证系统。通过构建一个通用系统或框架,我们可以减少软件项目的维护时间。而且整个系统也很容易理解。
结论
这个演示将帮助您开发您的 SQL 框架。