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
"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
@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. –
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