使用存储过程插入或更新整数的最佳方法是什么?

时间:2017-07-14 16:15:10

标签: c# asp.net sql-server stored-procedures

我有一张名为Employees的表。

此表每天使用Active Directory中的预定作业进行更新。

我们目前有以下存储过程,用于检查Employee表中是否存在特定员工。

如果是,请更新该表中的其余员工记录。

如果不是,则将员工记录插入该员工表。

为了确定员工表中是否存在员工,员工必须首先输入他们的员工ID。这不是自动生成的ID。如果该员工记录存在于Active Directory中,则会将其与Active Directory中的其余员工记录一起导入到Employee表中。

我们遇到的问题是我们无法在Employee表中插入新的员工记录。我们都无法更新记录。

我们不断收到以下信息:

无法将值NULL插入列' employeeID',table' Employees&#39 ;;列不允许空值。 INSERT失败。该语句已被终止。

我怀疑问题出在我的存储过程中,但不确定问题是什么。

非常感谢任何帮助。

这是我的存储过程以及我用来尝试调用它的代码。

ALTER PROCEDURE [dbo].[usp_Employees] 
 @FullName       varchar(75),
 @address     varchar(100),
 @city        varchar(50),
 @state       varchar(50),
 @zip         varchar(50),
 @eid  int = 0 OUTPUT
AS
BEGIN
  SET NOCOUNT ON;
  begin tran
  if exists (select * from Employees where employeeID = @eid)
   begin
    UPDATE Employees SET [empFullName] = @FullName
      ,[Address] = @address
      ,[City] = @city
      ,[State] = @state
      ,[Zip] = @zip where employeeID = @eid
    end
    else
    begin
  INSERT INTO [dbo].[Employees]
           ([empFullName]
           ,[Address]
           ,[City]
           ,[State]
           ,[Zip]
           ,[employeeID])
     VALUES
           (@FullName
           ,@address
           ,@city
           ,@state
           ,@zip
           ,@eid)

  SET @eid = SCOPE_IDENTITY()
  end
  commit tran
END



            int eid = 0;

            SqlCommand cmd = new SqlCommand("usp_Employees", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@FullName", txtfname.Text);
            cmd.Parameters.AddWithValue("@address", txtfaddress.Text);
            cmd.Parameters.AddWithValue("@city", txtcity.Text);
            cmd.Parameters.AddWithValue("@state", ddlstates.SelectedValue);
            cmd.Parameters.AddWithValue("@zip", txtfzip.Text);
            SqlParameter employeeID = cmd.Parameters.Add("@eid", SqlDbType.Int);
            employeeID.Direction = ParameterDirection.Output;

            cmd.ExecuteNonQuery();

            eid = Convert.ToInt32(employeeID.Value);

我需要在插入或更新后获取此employeeID并将其插入其他表中。

3 个答案:

答案 0 :(得分:2)

我认为您的问题只是您没有按原样传递员工ID。将其与其余代码一起传入,并丢弃输出和SCOPE_IDENTITY。修改C#将其与其余的一起添加到存储过程中,它应该没问题。此外,不确定在没有try / catch的情况下使用BEGIN TRAN和COMMIT TRAN来提交或回滚。否则它只是有或没有承诺:

ALTER PROCEDURE [DBO].[USP_EMPLOYEES] 
 @FULLNAME       VARCHAR(75),
 @ADDRESS       VARCHAR(100),
 @CITY          VARCHAR(50),
 @STATE         VARCHAR(50),
 @ZIP           VARCHAR(50),
 @EMPLOYEEID    INT     ,
 @EID           INT 
AS
BEGIN
  SET NOCOUNT ON;
  BEGIN TRAN
      IF EXISTS (SELECT * FROM EMPLOYEES WHERE EMPLOYEEID = @EID)
       BEGIN
        UPDATE EMPLOYEES 
        SET [EMPFULLNAME] = @FULLNAME
          ,[ADDRESS] = @ADDRESS
          ,[CITY] = @CITY
          ,[STATE] = @STATE
          ,[ZIP] = @ZIP 
         WHERE EMPLOYEEID = @EID
        END
        ELSE
        BEGIN
          INSERT INTO [DBO].[EMPLOYEES]
                   ([EMPFULLNAME]
                   ,[ADDRESS]
                   ,[CITY]
                   ,[STATE]
                   ,[ZIP]
                   ,[EMPLOYEEID])
             VALUES
                   (@FULLNAME
                   ,@ADDRESS
                   ,@CITY
                   ,@STATE
                   ,@ZIP
                   ,@EID)

      END
  COMMIT TRAN
END

答案 1 :(得分:1)

您可以使用MERGE(从Sql Server 2008开始)

MERGE Employees AS target  
USING (SELECT @eid, 
              @fullName, 
              @address, 
              @city,
              @state, 
              @zip) AS source (eid, fullName, address, city, state, zip)  
ON (target.employeeID = source.eid)  
WHEN MATCHED THEN   
    UPDATE SET 
        empFullName = source.fullName,
        Address = source.address,
        City = source.city,
        State = source.state,
        Zip = source.zip
WHEN NOT MATCHED THEN  
    INSERT (employeeID, empFullName, Address, City, State, Zip)  
    VALUES (source.eid, 
            source.fullName, 
            source.address, 
            source.city, 
            source.state, 
            source.zip)  
OUTPUT inserted.employeeID; -- return updated or inserted Id

答案 2 :(得分:-1)

...
  @eid  int
as
begin
...
  SET @eid = SCOPE_IDENTITY()
  INSERT INTO [dbo].[Employees]
           ([empFullName]
           ,[Address]
           ,[City]
           ,[State]
           ,[Zip]
           ,[employeeID])
     VALUES
           (@FullName
           ,@address
           ,@city
           ,@state
           ,@zip
           ,@eid)