5 Stimmen

Wie erhält man die nächste Identitätsnummer, die in SQL Server 2005 und ASP verwendet wird?

Bisher habe ich die nächste verfügbare Autonummer in Access durch eine einfache Abfrage wie folgt ermittelt:

SELECT RecordNumber, Info 
FROM myTABLE 
WHERE 0 = 1

Auf diese Weise könnte ich eine Variable erstellen, die den currentRecord enthält, und es wird dieselbe automatische Nummer verwendet, die Access beim Aktualisieren der Zeile verwenden würde

Ejemplo

rs.AddNew
currentRecord = rs("RecordNumber")

rsInfo = "SomeFormData" & currentRecord
rs.Update
rs.Close

Dies funktioniert in MS Access, aber in SQL Server 2005 erhalte ich die Identität, die durch den neuen Datensatz erstellt wurde, nicht zurück. "SomeFormData" wird korrekt eingefügt, das Feld RecordNumber in SQL wird durch die neue Autonummer gefüllt, aber ich habe die RecordNumber nicht in meinen Variablen, und ich brauche sie, um damit fortzufahren, verwandte Formulare auszufüllen, die Daten in verwandte Tabellen speichern und die currentRecord-Nummer speichern müssen.

Frage : Gibt es eine Möglichkeit, diese eindeutige Nummer bei einer neuen Einfügung wieder zu erhalten?

10voto

P Daddy Punkte 27687

IDENT_CURRENT('tableName') (einschließlich der einfachen Anführungszeichen) gibt den aktuellen Wert der Identität für die angegebene Tabelle zurück. Dieser Wert sollte der zuletzt zugewiesene Identitätswert sein, der in der Tabelle verwendet wird. Mit anderen Worten: Sie haben bereits eine Zeile mit diesem Identitätswert in der Tabelle, es sei denn, diese Zeile wurde gelöscht. Der Identitätswert, der beim nächsten Mal zugewiesen wird INSERT wird sein IDENT_CURRENT('tableName') + IDENT_INCR('tableName') .

Ich empfehle jedoch nicht, sich darauf zu verlassen. Wenn Sie den nächsten Identitätswert auf diese Weise im Voraus festlegen, werden Sie zwangsläufig in eine Situation geraten, in der ein anderer Prozess die Einfügung vornimmt, der diese ID tatsächlich vor Ihrem Prozess erhält, sodass Ihr Prozess am Ende den falschen ID-Wert verwendet.

Es ist viel besser, zuerst die Einfügung vorzunehmen (auch wenn Sie noch nicht alle Daten haben), und die SCOPE_IDENTITY() um die tatsächlich zugewiesene ID zu erhalten.

Sie fragen sich vielleicht, warum SCOPE_IDENTITY() ist besser als IDENT_CURRENT('tableName') . Wie der Name schon sagt, erhalten Sie mit ersterem den letzten Identitätswert, der in Ihrem aktuellen Bereich (Ihrem Batch, Ihrem Stored Proc, was auch immer) zugewiesen wurde, während Sie mit letzterem die letzte Identität erhalten, die in der Tabelle von irgendjemandem zugewiesen wurde. Auch wenn Sie vielleicht IDENT_CURRENT direkt nach ' INSERT ist es immer noch möglich, dass die von jemand anderem INSERT tritt dazwischen auf, und IDENT_CURRENT gibt Ihnen den Identitätswert, der sich aus leur einfügen, während SCOPE_IDENTITY wird Ihnen immer das Ihre geben.

エディテージ :

Es ist auch erwähnenswert, dass SCOPE_IDENTITY() wird gegenüber der ähnlich funktionierenden @@IDENTITY . Beide geben den letzten Identitätswert zurück, der innerhalb der aktuellen Charge zugewiesen wurde, @@IDENTITY wird durch Einfügungen innerhalb von Auslösern beeinflusst; SCOPE_IDENTITY() ist nicht.

1voto

Andrew Bullock Punkte 35376

SELECT CAST(Bereich_Identität() AS INT)

0voto

Chris Catignani Punkte 4512

Ich weiß, diese Frage ist alt... aber Sie können die ID der eingefügten Datensätze mit Hilfe eines Ausgabeparameters abrufen.

Hier ein Beispiel für eine gespeicherte Prozedur, die ich habe

IF object_id('spOrganizationAdd') IS NOT NULL
    DROP PROCEDURE spOrganizationAdd;
GO

CREATE PROCEDURE dbo.spOrganizationAdd
    @OrganizationName VARCHAR(50),
    @ReturnIdentityValue INT OUTPUT
AS
BEGIN
    DECLARE @TempOrganizationIdentity TABLE (TempOrganizationID INT)

    INSERT INTO Organization (OrganizationName)
    OUTPUT INSERTED.OrganizationID INTO @TempOrganizationIdentity
    VALUES (@OrganizationName)

    SELECT @ReturnIdentityValue = (SElECT TempOrganizationID FROM @TempOrganizationIdentity)
END
GO

Hier ein Beispiel für den C#-Code, der es aufruft...Hinweis ParameterDirection.Output :

public static int AddOrganization(Organization oOrganization)
{
    int iRetVal = 0;

    using (SqlConnection conn = Connection.GetConnection())
    {
        using (SqlCommand cmd = new SqlCommand("spOrganizationAdd", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@OrganizationName", oOrganization.OrganizationName);
            cmd.Parameters.Add("@ReturnIdentityValue", SqlDbType.Int).Direction = ParameterDirection.Output;

            conn.Open();
            cmd.ExecuteNonQuery();
            iRetVal = Convert.ToInt32(cmd.Parameters["@ReturnIdentityValue"].Value);
        }
    }

    return iRetVal;
}

Beispiel einer Klasse

public class Organization
{
    public Organization() { }
    public Organization(int organizationID) { OrganizationID = organizationID; }

    public int OrganizationID { get; set; }
    public string OrganizationName { get; set; }

    public string Display()
    {
        return OrganizationID.ToString() + " " + OrganizationName;
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X