这是我的方法:
您可以在客户端验证所有 UI 端验证,例如长度等。这样您就无需前往应用程序和数据库服务器。
这里的数据操作是我多次实现的方法。
创建一个必须包含您需要处理的所有列的表类型。
-
在存储过程中使用该表类型变量作为输入参数,您可以在其中一次性传递 n 行,这样您就无需在 c# 处循环多次访问数据库。
存储过程中的用户合并语句如果记录不匹配,您可以插入它,如果匹配,您可以根据需要更新它。您也可以在事务中执行此操作。
希望这会对你有所帮助。
编辑 1:基于您对数据库级验证的评论。
在数据库端会有两种类型的错误。
1.数据本身不会是sql表定义所期望的格式,比如数据类型转换失败。
- DDL 级别错误,如数据长度超出或外键约束等。
我建议对可以在 c# 级别编码的数据进行所有可能的验证。就像基于您的目标列的数据长度一样。调用存储过程之前的数据类型,您可以在 c# 级别过滤此类记录。在这个级别,您可以进行最大程度的验证。
一旦您将数据传递到 sql server,您就可以在 SQL server 中使用try and catch,您可以在其中实现失败行的逻辑。将失败的行保留在临时表中,您可以稍后返回并成功插入所有行。
编辑 2:这是可能的代码。
CREATE TABLE Users
(
Idx BIGINT IDENTITY(1,1),
UserID UNIQUEIDENTIFIER,
FirstName VARCHAR(100),
LastName VARCHAR(100),
Email VARCHAR(100),
UserPassword VARCHAR(100),
InsertDate DATETIME,
UpDateDate DATETIME,
IsActive BIT,
CONSTRAINT [Users_PK] PRIMARY KEY CLUSTERED
(
[UserID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
CREATE TYPE UT_Users AS TABLE
(
Idx INT,
FirstName VARCHAR(100),
LastName VARCHAR(100),
Email VARCHAR(100),
UserPassword VARCHAR(100),
InsertDate DATETIME,
UpDateDate DATETIME,
IsActive BIT
)
GO
CREATE PROCEDURE uspInsertUsers(@user_Details [UT_Users]) READONLY
AS
BEGIN
DECLARE @Counter INT=1
DECLARE @TotalRows INT=0
SELECT @TotalRows = COUNT(1) FROM @user_Details
WHILE @TotalRows>@Counter
BEGIN
TRY
BEGIN
INSERT INTO dbo.Users
SELECT * FROM @user_Details WHERE @Counter = Idx
END
CATCH
BEGIN
--write code for catching the error as per your need. Store row in temp tables and return the temp table at the end
END
SET @Counter = @Counter+1
END
END
GO
DECLARE @user_Details AS [UT_Users];
INSERT @user_Details
SELECT 1,'Rahul','Neekhra','rahul@india.com','12345',GETDATE(),GETDATE(),1 UNION
SELECT 2,'James','Streak','streak@usa.com','12345',GETDATE(),GETDATE(),1
EXEC uspInsertUsers @user_Details