SQL Server 中的存储过程,它采用表值参数并插入不存在的并返回存在的

Posted

技术标签:

【中文标题】SQL Server 中的存储过程,它采用表值参数并插入不存在的并返回存在的【英文标题】:Stored procedure in SQL Server which takes table-valued parameter and insert which does not exists and returns which exists 【发布时间】:2015-10-17 06:44:48 【问题描述】:

我正在编写一个存储过程,它将一个表值参数作为输入参数,如果提供的参数中的所有行都是唯一的并且在表User 中不存在并且已经存在的行将是作为输出返回为Duplicate

用户

    ╔════╦═════════════════════════╦══════════════════╦═══════════╦════════════╦══════════╦════════╦════════════╦═══════════════╦════════════╦════════════╦══════════════╗
    ║ id ║        DateField        ║  registrationno  ║ firstname ║ middlename ║ lastname ║ gender ║    dob     ║ maritalstatus ║  mobileno  ║ landlineno ║   emailid    ║
    ╠════╬═════════════════════════╬══════════════════╬═══════════╬════════════╬══════════╬════════╬════════════╬═══════════════╬════════════╬════════════╬══════════════╣
    ║  1 ║ 2015-10-16 16:24:27.460 ║ U/10/2015/000001 ║ John      ║ NULL       ║ Doe      ║      1 ║ 1990-10-09 ║             1 ║ 1234567890 ║ 1234567890 ║ jd@gmail.com ║
    ║  2 ║ 2015-10-16 16:24:27.460 ║ U/10/2015/000002 ║ Bean      ║ NULL       ║ Bean     ║      1 ║ 1986-18-12 ║             1 ║ 9874561230 ║ 9874561230 ║ bb@gmail.com ║
    ║  3 ║ 2015-10-16 16:24:27.460 ║ U/10/2015/000003 ║ Jennifer  ║ NULL       ║ Lopez    ║      2 ║ 1980-09-16 ║             1 ║ 9985632147 ║ 9985632147 ║ jl@gmail.com ║
    ║  4 ║ 2015-10-16 16:24:27.460 ║ U/10/2015/000004 ║ Maria     ║ NULL       ║ Stewart  ║      2 ║ 2000-10-15 ║             1 ║ 7458612390 ║ 7458612390 ║ ms@gmail.com ║
    ╚════╩═════════════════════════╩══════════════════╩═══════════╩════════════╩══════════╩════════╩════════════╩═══════════════╩════════════╩════════════╩══════════════╝

表格类型UserTableType

CREATE TYPE [dbo].[UserTableType] AS TABLE
(
    [FirstName] [nvarchar](max) NULL,
    [MiddleName] [nvarchar](max) NULL,
    [Lastname] [nvarchar](max) NULL,
    [Gender] [nvarchar](max) NULL,
    [DateOfBirth] [date] NULL,
    [MaritalStatus] [nvarchar](max) NULL,
    [MobileNo] [nvarchar](max) NULL,
    [LandlineNo] [nvarchar](max) NULL,
    [EmailId] [nvarchar](max) NULL
)
GO

就我所写的程序而言:

Create PROCEDURE [dbo].[uspManageUser] 
        @UserTableType dbo.User READONLY
AS
BEGIN

SET NOCOUNT ON;

    BEGIN TRY
        DECLARE @countI INT , @countU INT, @countT INT

        SELECT @countI = count(temp.MobileNo) 
        FROM 
            (SELECT 
                    VPM.FirstName, VPM.MiddleName, VPM.LastName, 
                    CASE VPM.Gender 
                    WHEN 'Male' THEN '1' 
                    WHEN 'Female' THEN 'G2' 
                    END AS [Gender], 
                    getdate() as 'DOB', 
                    CASE VPM.MaritalStatus 
                    WHEN 'Single' THEN 1 
                    END as 'MaritalStatus', 
                    VPM.MobileNo, VPM.LandlineNo, 
                    VPM.EmailId, VPM.Occupation, 
                    VPM.Address1, VPM.Address2, VPM.City, VPM.Pincode
                FROM 
                    @UserTableType AS VPM
                LEFT JOIN 
                    User AS DPM ON DPM.MobileNo = VPM.MobileNo AND VPM.EmailId = DPM.EmailId) temp

        SET @countT= @countI    
        Select @countT

        INSERT INTO 
            dbo.[User](DateField, FirstName,  MiddleName,  LastName,  Gender, dob,   MaritalStatus,  MobileNo, LandlineNo,  EmailId)
        SELECT 
            Getdate(), 
            VPM.FirstName, 
            VPM.MiddleName, 
            VPM.LastName, 
        CASE 
            VPM.Gender  when 'Male'   then 'GE001' 
                        when 'Female' then 'GE002' END,
            getdate(),
        CASE 
            VPM.MaritalStatus when 'Single' then 1 end,
            VPM.MobileNo,
            VPM.LandlineNo,
            VPM.EmailId,
            VPM.Occupation,
            VPM.Address1,
            VPM.Address2,
            VPM.City,
            VPM.Pincode
        FROM
            @UserTableType AS VPM
        LEFT JOIN 
            [User] AS DPM ON DPM.MobileNo = VPM.MobileNo AND VPM.EmailId = DPM.EmailId

        RETURN 1

    END TRY

BEGIN CATCH 
    RETURN -1
END CATCH
END

我想要的是一个存储过程,在其中我从 UserTableType 参数读取数据,如果有重复,我将根据 User.MobileNoUser.EmailId 检查,因为它们是唯一字段User 表,如果给定的User.MobileNoUser.EmailId 不存在记录,则如果User.MobileNoUser.EmailId 存在记录,则将插入否则返回输出将是User 中已经存在的结果集表

这方面怎么做?

【问题讨论】:

那么你的实际问题是什么,除了写代码? 我的问题是我无法正常工作,请查看代码并尽可能提供帮助。 您明白 Stack Overflow 是用来提问的,而不是调试代码的问题吗? 【参考方案1】:

只是猜测您需要什么,但这里有一些您可能需要的(伪)代码。

返回已经存在的行:

select * from @UserTableType VPM
where exists (
  select 1 from User DPM
  where DPM.MobileNo = VPM.MobileNo AND VPM.EmailId = DPM.EmailId
)

插入不存在的行:

insert into User ("list of columns")
select "list of columns" from @UserTableType VPM
where not exists (select 1 from User DPM
  where DPM.MobileNo = VPM.MobileNo AND VPM.EmailId = DPM.EmailId
)

【讨论】:

以上是关于SQL Server 中的存储过程,它采用表值参数并插入不存在的并返回存在的的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JDBC 将表值参数(类数组参数)传递给 Microsoft SQL Server 2008 R2 中的存储过程? [复制]

SQL Server:表值函数与存储过程

SQL Server存储过程中使用表值作为输入参数示例

为啥需要以只读方式输入 SQL Server 存储过程的表值参数?

Snowflake 中的存储过程能否提供一个表值输出,就像我们在 SQL Server 中得到的一样

表值参数