2017-11-01 1 views
2

SzenarioDatensatz kann nicht von einfügen benutzerdefinierte in Tabelle

ich ein Geschäft Verfahren geschaffen, in dem habe ich eine benutzerdefinierte Tabelle als Parameter nehme dann Zunächst werde ich, wenn Role_ID überprüfen und Form_ID ist vorhanden, dann werde ich meine vorhandene Tabelle aktualisieren. Ansonsten werde ich in bestehende Tabelle einfügen.

Problem

Nach INSERT-Abfrage in meinem Speicher Prozedur schreibt ich unter Fehlern bekam während meines Speichers Prozedur zu ändern.

Msg 137, Ebene 16, Status 1, Prozedur SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE, Zeile 17 muss die skalare Variable "@Temp" deklarieren. Msg 137, Ebene 16, Status 1, Prozedur SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE, Zeile 17 Muss die Skalarvariable "@Temp" deklarieren.

Unten ist mein SP-Code:

CREATE TYPE _ROLERIGHTSSCHEMA as Table (
    _Role_ID int, 
    _Form_ID int, 
    _Form_Name varchar(100), 
    _Can_View bit, 
    _Can_Edit bit, 
    _Can_Prepare_By bit, 
    _Can_Change_Status_By bit, 
    _Prepared_By_ID int, 
    _Prepared_Date datetime 
) 

ALTER PROCEDURE SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE 
(@Temp _ROLERIGHTSSCHEMA ReadOnly) 
AS 
BEGIN 
    IF EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID) 
    BEGIN 
     Update Role_Rights 
     set Can_View = t._Can_View, 
      Can_Edit = t._Can_Edit, 
      Can_Prepare_By = t._Can_Prepare_By, 
      Can_Change_Status_By = _Can_Change_Status_By, 
      Modified_By_ID = 0, 
      Modified_Date = GETDATE() 
      From @Temp t 
      WHERE Role_Rights.Role_ID = t._Role_ID and Role_Rights.Form_ID = t._Form_ID 
     END 
    ELSE 
    BEGIN 
     INSERT INTO Role_Rights (
      Role_ID, 
      Form_ID, 
      Can_View, 
      Can_Edit, 
      Can_Prepare_By, 
      Can_Change_Status_By, 
      Prepared_By_ID, 
      Prepared_Date 
     ) SELECT _Role_ID, _Form_ID, _Can_View, _Can_Edit, _Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE() FROM @Temp 
    END 
END 

enter image description here

+1

funktioniert sollten Sie berücksichtigen nicht die SP_ Präfix. Dies kann zu Leistungsproblemen und anderen interessanten Herausforderungen führen. Wählen Sie entweder ein anderes Präfix oder noch besser, überhaupt kein Präfix. http://sqlperformance.com/2012/10/t-sql-queries/sp_prefix –

Antwort

1

Um mehrere Datensätze einmal zu aktualisieren/einfügen bei MERGE verwenden:

ALTER PROCEDURE SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE 
(@Temp _ROLERIGHTSSCHEMA ReadOnly) 
AS 
BEGIN 
    MERGE Role_Rights rr 
    USING @Temp t 
     ON rr.Role_ID = t._Role_ID 
     and rr.Form_ID = t._Form_ID 
    WHEN MATCHED THEN 
     Update set Can_View = t._Can_View, 
        Can_Edit = t._Can_Edit, 
        Can_Prepare_By = t._Can_Prepare_By, 
        Can_Change_Status_By = _Can_Change_Status_By, 
        Modified_By_ID = 0, 
        Modified_Date = GETDATE() 
    WHEN NOT MATCHED BY TARGET THEN 
     INSERT (Role_ID, 
      Form_ID, 
      Can_View, 
      Can_Edit, 
      Can_Prepare_By, 
      Can_Change_Status_By, 
      Prepared_By_ID, 
      Prepared_Date) 
     VALUES (_Role_ID, _Form_ID, _Can_View, _Can_Edit, 
       _Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE()); 
END; 

EDIT:

MERGE über IF EXISTS/UPDATE/INSERT set based:

Single insert -- no difference 
Single update -- no difference 
Multiple insert -- no difference 
Multiple update -- no difference 
Multiple insert/update: MERGE  -- will handle it correctly 
         IF EXISTS -- you will lose records to insert 

UPDATE/INSERT ohne Teil IF:

Update Role_Rights 
     set Can_View = t._Can_View, 
      Can_Edit = t._Can_Edit, 
      Can_Prepare_By = t._Can_Prepare_By, 
      Can_Change_Status_By = _Can_Change_Status_By, 
      Modified_By_ID = 0, 
      Modified_Date = GETDATE() 
      From @Temp t 
WHERE Role_Rights.Role_ID = t._Role_ID and Role_Rights.Form_ID = t._Form_ID; 

INSERT INTO Role_Rights (
     Role_ID, 
     Form_ID, 
     Can_View, 
     Can_Edit, 
     Can_Prepare_By, 
     Can_Change_Status_By, 
     Prepared_By_ID, 
     Prepared_Date 
    ) 
SELECT _Role_ID, _Form_ID, _Can_View, _Can_Edit, 
     _Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE() 
FROM @Temp t 
WHERE NOT EXISTS (SELECT 1 
        FROM Role_Rights rr 
        WHERE rr.Role_ID = t._Role_ID 
        and rr.Form_ID = t._Form_ID); 
+0

Bevor ich geschrieben habe, wenn Bedingung über Update Abfrage funktioniert gut. Ich habe einen einzelnen Datensatz aktualisiert, aber nach dem Schreiben der 'IF'-Bedingung funktioniert mein Einfügecode nicht. –

+0

@AhmerAliAhsan Die Verwendung von IF/UPDATE/INSERT funktioniert nicht für mehrere Datensätze. – lad2025

+0

Zuerst habe ich Ihre Antwort überprüft und es hat gut funktioniert. Aber nach @sm Antwort antworte ich einfach meine "IF" Bedingung und es funktionierte wie ein Zauber. –

1

Die Anweisung in der Klausel existiert nicht korrekt gebildet wird - und das den Fehler zu werfen. Sie haben:

IF EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID) 

Aber es sollte sein:

if exists (select * from ROLE_RIGHTS as rr inner join @Temp as tp on rr.Role_ID = tp._Role_ID and rr.Form_ID = tp._Form_ID) 

Diese Korrektur ist sinnlos - wie @ lad2025 bereits erwähnt hat.

+0

Bearbeitet und arbeiten jetzt wie ein Charme. –

+0

Es gibt einen großen Nachteil, wenn dieser Ansatz verwendet wird (wenn @Temp-Tabelle beide Datensätze zum Aktualisieren/Einfügen haben - es wird überhaupt kein Insert-Teil geben). Natürlich könnte OP CURSOR benutzen und jede Zeile separat behandeln, aber es wird viel langsamer als der Satz basierte Ansatz sein. – lad2025

0

mit mehreren Versuchen IF-Klauseln innerhalb Anweisung nach ELSE, ob diese

CREATE TYPE _ROLERIGHTSSCHEMA as Table (
     _Role_ID int, 
     _Form_ID int, 
     _Form_Name varchar(100), 
     _Can_View bit, 
     _Can_Edit bit, 
     _Can_Prepare_By bit, 
     _Can_Change_Status_By bit, 
     _Prepared_By_ID int, 
     _Prepared_Date datetime 
    ) 


    ALTER PROCEDURE SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE 
    (@Temp _ROLERIGHTSSCHEMA ReadOnly) 
    AS 
    BEGIN 
     IF EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID) 
     BEGIN 
      Update Role_Rights 
      set Can_View = t._Can_View, 
       Can_Edit = t._Can_Edit, 
       Can_Prepare_By = t._Can_Prepare_By, 
       Can_Change_Status_By = _Can_Change_Status_By, 
       Modified_By_ID = 0, 
       Modified_Date = GETDATE() 
       From @Temp t 
       WHERE Role_Rights.Role_ID = t._Role_ID and Role_Rights.Form_ID = t._Form_ID 
      END 
     ELSE 
     BEGIN 
     IF NOT EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID) 
     BEGIN 
      INSERT INTO Role_Rights (
       Role_ID, 
       Form_ID, 
       Can_View, 
       Can_Edit, 
       Can_Prepare_By, 
       Can_Change_Status_By, 
       Prepared_By_ID, 
       Prepared_Date 
      ) SELECT _Role_ID, _Form_ID, _Can_View, _Can_Edit, _Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE() FROM @Temp 
     END 
     END 
    END 
Verwandte Themen