2017-07-14 1 views
0

Ich habe eine Tabelle namens Mitarbeiter.Was ist der beste Ansatz zum Einfügen oder Aktualisieren einer ganzen Zahl mit gespeicherten Prozedur?

Diese Tabelle wird täglich mit einem geplanten Auftrag aus Active Directory aktualisiert.

Derzeit haben wir die folgende gespeicherte Prozedur, die überprüft, ob ein bestimmter Mitarbeiter in der Employee-Tabelle vorhanden ist.

Wenn ja, aktualisieren Sie die restlichen Mitarbeiterdatensätze in dieser Tabelle.

Wenn nicht, dann fügen Sie den Mitarbeiterdatensatz in diese Mitarbeitertabelle ein.

Um festzustellen, ob ein Mitarbeiter in der Employee-Tabelle vorhanden ist oder nicht, müssen die Mitarbeiter zuerst ihre employeeID eingeben. Dies ist keine automatisch generierte ID. Es wird zusammen mit dem Rest der Mitarbeiterdatensätze aus Active Directory in die Employee-Tabelle importiert, wenn dieser Mitarbeiterdatensatz in Active Directory vorhanden ist.

Das Problem, das wir haben, ist, dass wir nicht in der Employee-Tabelle einen neuen Mitarbeiterdatensatz einfügen können. Wir können den Datensatz auch nicht aktualisieren.

Wir hielten die Nachricht bekommen, dass:

kann nicht den Wert NULL in Spalte 'employeeID' einfügen, Tabelle 'Employees'; Spalte erlaubt keine Nullen. INSERT schlägt fehl. Die Anweisung wurde beendet.

Ich vermute, das Problem ist mit meiner gespeicherten Prozedur, aber nicht sicher, was das Problem ist.

Jede Hilfe wird sehr geschätzt.

Hier ist meine gespeicherte proc und der Code, den ich verwende, um zu versuchen, es aufzurufen.

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); 

Ich muss diese employeeID nach dem Einfügen oder zu aktualisieren und in andere Tabellen einfügen.

+0

Ist MitarbeiterID eine Identitätsspalte? Oder ein Standard INT? Vermutlich möchten Sie, dass es einzigartig ist. @eid ist ein Ausgabeparameter, daher wird es Ihnen schwer fallen, es in der Einfügung zu verwenden, und Sie erhalten nicht die MAX ID oder ähnliches. Ihre Verwendung von SCOPE_IDENTITY schlägt vor, dass employeeID eine Identitätsspalte ist. Wenn dies der Fall ist, müssen Sie sie nicht in das INSERT aufnehmen, da SQL sich darum kümmert. – Leonidas199x

+0

@ Leonidas199x, wie in meinem Original angegeben, ist es keine Auto-Inkrement-ID. Also, nein, es ist keine Identität. Es wird zusammen mit den übrigen Mitarbeiterdaten in die Tabelle Mitarbeiter importiert. – Kenny

+0

@Kenny Warum verwenden Sie dann SCOPE_IDENTITY? Ich glaube nicht, dass das tut, was Sie denken, wenn Sie keine Identitätsspalte verwenden. – Leonidas199x

Antwort

1

Sie können MERGE verwenden (beginnend mit 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 
+0

Ich habe Merge noch nicht verwendet. Ist das immer noch Teil des gespeicherten Proc? – Kenny

+0

Sie können es in gespeicherten Prozeduren verwenden – Fabio

+0

Wie wusste ich nicht über 'MERGE'? Das wird mein Leben verändern ... Danke. –

-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) 
+0

Bitte formatieren Sie Ihre Antwort richtig, erklären Sie das Problem und wie Ihr Code es behebt. Stellen Sie nicht einfach einen rohen Code-Dump bereit. – mason

2

Ich denke, das Problem ist einfach Sie sind nicht die Mitarbeiter-ID vorbei in wie es sein sollte. Übergeben Sie es mit dem Rest des Codes und verwerfen Sie die Ausgabe und SCOPE_IDENTITY. Ändern Sie C#, um es zusammen mit dem Rest zum gespeicherten Proc hinzuzufügen, und es sollte in Ordnung sein. Außerdem bin ich mir nicht sicher, ob ich BEGIN TRAN und COMMIT TRAN ohne try/catch verwenden soll, um entweder Commit oder Rollback durchzuführen. Andernfalls wird nur mit oder ohne committed:

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 
+0

Danke Jungs sehr. – Kenny

Verwandte Themen