Proponuję, aby twoje komendy C# i T-SQL "partie" były całkowicie od siebie oddzielone.
Wyobraź sobie, że SQLCommand jest tylko opakowaniem wykonawczym, w ramach którego rzeczywistą definicję tego, co składa się na partię, definiuje się i kontroluje za pomocą języka T-SQL.
Twój zakres sesji jest utrzymywany na poziomie obiektu Połączenia.
Prawdopodobnie na poniższym stanowisku MSDN post pojawi się interesująca lektura. Zwróć uwagę, że początkowy przykład wykonuje dwa oddzielne polecenia SQL, ale funkcja SCOPE_IDENITY() drugiego połączenia może zobaczyć wynik poprzedniego połączenia. Dzieje się tak, ponieważ bieżący zakres jest widoczny na poziomie połączenia.
SQLCommand With Parameters and Scope_Indentity
Dla kompletności wyjaśnienia, powód dlaczego to nie działa za pomocą parametrów, jak później wykazano w połączonej przykład dlatego sp_executesql jest wykonywana w jego własnym zakresie i tak więc nie widzę zakresu wynalazku połączenie.
[Edycja]
Dalsze odczytu dla dociekliwsza czytnika można znaleźć kod VB.NET poniżej przedstawia przykład wykonania dwa oddzielne polecenia na pojedynczego połączenia, przy czym drugie polecenie powodzeniem wystawienia SCOPE_IDENTITY() Funkcja.
Kod źródłowy można wykonać z poziomu komponentu SCRIPT zadania pakietu SSIS. Będziesz także musiał edytować szczegóły połączenia dla swojego środowiska, a także utworzyć obiekt tabeli, do którego się odwołujesz.
Utwórz skrypt tabeli:
create table TestTable
(
ID int identity(1,1) primary key not null,
SomeNumericData int not null
);
VB.NET nieruchomość Źródło:
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
"dzieje się tak, ponieważ zakres jest utrzymany/widoczny na poziomie połączenia." nie zgadzam się z tobą. Zakres jest określony przez miejsce, w którym określasz parametr scope_identity() w zapytaniu, w połączonym przykładzie 1, w 2 kwerendach wykonanych różnych poleceń. ponieważ oba są w różnym zakresie, zwraca wartość null ... Tak więc zakres dotyczy tylko polecenia ... nie połączenia ... – RameshVel
@Ramesh Vel: znajdź edycję oryginalnego wpisu, aby dołączyć kod źródłowy, który sprawdza poprawność widoczności zakresu sesji przez dwa oddzielne polecenia w obrębie połączenia. –
Zrobiłem prawie ten sam rodzaj testu, ale w C# i wykonanie SCOPE_IDENTITY() w osobnych poleceniach działa dobrze, mimo że wstawiłem kilka rekordów do tabeli pomiędzy wywołaniem wstawić i wybrać scope_identity() (aplikacja konsoli , ReadLine() między poleceniami) – kubal5003