2010-10-12 15 views
10

Ich habe die Dokumentation für SCOPE_IDENTITY() überprüft, und es heißt "Ein Bereich ist ein Modul: eine gespeicherte Prozedur, Trigger, Funktion oder Batch." Das ist einfach, wenn ich eine Abfrage in SSMSE ausführe, aber in C# verwende ich SqlCommand für die Ausführung meiner Anweisungen.SCOPE_IDENTITY in C# - Bereich

Die Frage ist: Was ist der Umfang dort? Führt nachfolgende Befehle unter einer Verbindung ein Äquivalent von Batch? Oder ist vielleicht jeder Befehl in einem anderen Bereich und ich brauche eine Transaktion, damit das funktioniert?

Antwort

7

Ich schlage vor, dass Sie Ihre C# -Befehle und T-SQL- "Batches" als vollständig voneinander getrennt betrachten.

Stellen Sie sich SQLCommand nur als Ihren Execution-Wrapper vor, innerhalb dessen die tatsächliche Definition eines Stapels definiert und von der T-SQL-Sprache gesteuert wird.

Ihr Sitzungsumfang wird auf der Verbindungsobjektebene beibehalten.

Sie werden wahrscheinlich das folgende MSDN forum posten interessante lesen finden. Beachten Sie, dass das anfängliche Beispiel zwei separate SQL-Befehle ausführt, die SCOPE_IDENITY() des zweiten Aufrufs jedoch das Ergebnis des vorherigen Aufrufs anzeigen kann. Dies liegt daran, dass der aktuelle Bereich auf der Verbindungsebene sichtbar ist.

SQLCommand With Parameters and Scope_Indentity

Für Vollständigkeit der Erklärung der Grund, warum dies nicht Parametern funktioniert, wie es später in der verknüpften Beispiel demonstriert, ist, weil Sp_executesql innerhalb seiner eigenen Bereich ausgeführt werden soll und so daher nicht den Umfang der sehen Verbindung.

[EDIT]

Literaturhinweise für die mehr neugierigen Leser, bitte VB.NET Code unter der Ausführung von zwei getrennten Befehlen auf einer einzelnen Verbindung ein Beispiel liefert, wobei der zweite Befehl den SCOPE_IDENTITY erfolgreich ausstellende() Funktion.

Der Quellcode kann aus der SCRIPT-Komponente eines SSIS-Pakets Task ausgeführt werden. Sie müssen auch die Verbindungsdetails für Ihre Umgebung bearbeiten und auch das referenzierte Tabellenobjekt erstellen.

Create Table Script:

create table TestTable 
(
    ID int identity(1,1) primary key not null, 
    SomeNumericData int not null 
); 

VB.NET Quelle Listing:

Imports System 
Imports System.Data 
Imports System.Math 
Imports Microsoft.SqlServer.Dts.Runtime 
Imports System.Data.SqlClient.SqlConnection 
Imports Windows.Forms.MessageBox 

Public Class ScriptMain 



    Public Sub Main() 
     ' 
     ' Add your code here 

     Dim oCnn As New Data.SqlClient.SqlConnection 
     Dim sSQL As String 
     Dim sSQL2 As String 
     Dim resultOne As Integer 
     Dim resultTwo As Integer 
     Dim messageBox As Windows.Forms.MessageBox 

     resultOne = 0 
     resultTwo = 0 

     oCnn.ConnectionString = "Server=ServerName;Database=DatabaseName;Trusted_Connection=true" 
     sSQL = "INSERT INTO TestTable(SomeNumericData) VALUES(666) " 
     sSQL2 = "SELECT SCOPE_IDENTITY()" 
     Dim oCmd As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL, oCnn) 
     Dim oCmd2 As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL2, oCnn) 

     oCmd.CommandType = CommandType.Text 
     oCmd.Connection = oCnn 
     oCnn.Open() 

     resultOne = oCmd.ExecuteNonQuery() 
     resultTwo = Convert.ToInt32(oCmd2.ExecuteScalar()) 

     oCnn.Close() 

     messageBox.Show("result1:" + resultOne.ToString + Environment.NewLine + "result2: " + resultTwo.ToString) 

     Dts.TaskResult = Dts.Results.Success 
    End Sub 
End Class 
+0

"Dies liegt daran, dass der Bereich auf der Verbindungsebene beibehalten/sichtbar ist." Ich bin mit Ihnen nicht einverstanden .. der Umfang wird durch bestimmt, wo Sie die scope_identity() in Ihrer Abfrage angeben, im verknüpften Beispiel 1, in 2 Abfragen verschiedenen Befehle ausgeführt. da beide in unterschiedlichem Umfang sind, gibt es null zurück ... Also der Umfang ist nur per Befehl. keine Verbindung ... – RameshVel

+0

@Ramesh Vel: Finden Sie eine Bearbeitung des ursprünglichen Posts, um Quellcode einzufügen, der die Sichtbarkeit des Sitzungsbereichs über zwei separate Befehle innerhalb einer Verbindung hinweg überprüft. –

+0

Ich habe fast die gleiche Art von Test gemacht, aber in C# und Ausführen von SCOPE_IDENTITY() in separaten Befehlen funktioniert gut, obwohl ich einige weitere Datensätze in die Tabelle zwischen dem Aufruf einfügen und select scope_identity() (Konsolenanwendung) einfügen , ReadLine() zwischen den Befehlen) – kubal5003

1

Ich glaube, Spielraum für die einzelnen Befehl nur anwendbar ist, nicht für die gesamte Verbindung.

strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT SCOPE_IDENTITY()" 
SQLCommand.CommandText = strSQL 
Id = SQLCommand.ExecuteScalar() 

im obigen Code strSQL ist ein kompletter Umfang und den @@ identity Wert der zugehörigen Insert-Anweisung immer wieder zurückkehren.

so haben die nachfolgenden Befehle ihren eigenen Bereich.

+0

Ich bin geneigt, mit Ihnen nicht zu stimmen. –

+0

@john, warum ist das so ?? – RameshVel

+0

@Ramesh Vel: Der folgende Beispielcode würde sonst scheinen vorschlagen: http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/080280b7-9c2d-4ee5-afe0-5c07d2affc7c –

Verwandte Themen