Sugiero pensar en sus comandos C# y T-SQL "Lotes" como completamente separados entre sí.
Piense en SQLCommand como su envoltorio de ejecución solamente, dentro del cual la definición real de lo que constituye un lote está definida y controlada por el lenguaje T-SQL.
El alcance de su sesión se mantiene en el nivel del objeto Connection.
Es probable que la siguiente publicación en el foro de MSDN le resulte interesante. Observe cómo el ejemplo inicial ejecuta dos comandos SQL separados, pero SCOPE_IDENITY() de la segunda llamada puede ver el resultado de la llamada anterior. Esto se debe a que el alcance actual es visible en el nivel de conexión.
SQLCommand With Parameters and Scope_Indentity
Para completar la explicación, la razón por la que esto no funciona utilizando parámetros, como más tarde se demostró en el ejemplo enlazado, se debe a sp_executesql se ejecuta dentro de su propio ámbito de aplicación y por lo tanto no puede ver el alcance de la conexión.
[EDIT]
Lectura adicional para el lector más curioso, por favor, encontrar el código VB.NET a continuación que proporciona un ejemplo de ejecución de dos comandos separados en una única conexión, con el segundo comando de emisión con éxito la SCOPE_IDENTITY() función.
El código fuente se puede ejecutar desde el componente SCRIPT de un paquete SSIS Tarea. También necesitará editar los detalles de conexión para su entorno y también crear el objeto de tabla al que se hace referencia.
crear tabla Guión:
create table TestTable
(
ID int identity(1,1) primary key not null,
SomeNumericData int not null
);
VB.NET Fuente de listado:
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
"esto es porque el alcance se mantiene/visible en el nivel de conexión." No estoy de acuerdo con usted. El alcance está determinado por el lugar donde especifica el scope_identity() en su consulta, en el ejemplo 1 vinculado, en 2 consultas ejecutadas diferentes comandos. dado que ambos tienen un alcance diferente, devuelve nulo ... Entonces el alcance es solo por comando ... no conexión ... – RameshVel
@Ramesh Vel: busque una edición en la publicación original para incluir el código fuente que valida la visibilidad del alcance de la sesión en dos comandos separados dentro de una conexión. –
He hecho casi el mismo tipo de prueba, pero en C# y ejecutar SCOPE_IDENTITY() en comandos separados funciona bien aunque estaba insertando más registros en la tabla entre la llamada para insertar y seleccionar scope_identity() (aplicación de consola , ReadLine() entre comandos) – kubal5003