Je suggère de penser à vos commandes C# et aux "lots" T-SQL comme étant complètement séparés les uns des autres. Pensez à SQLCommand comme votre enveloppe d'exécution uniquement, dans laquelle la définition réelle de ce qui constitue un lot est définie et contrôlée par le langage T-SQL.
Votre étendue de session est gérée au niveau de l'objet Connexion.
Vous trouverez probablement le forum MSDN suivant une lecture intéressante. Notez comment l'exemple initial exécute deux commandes SQL distinctes, mais le SCOPE_IDENITY() du second appel peut voir le résultat de l'appel précédent. C'est parce que la portée actuelle est visible au niveau de la connexion.
SQLCommand With Parameters and Scope_Indentity
Pour être complet d'explication, la raison pour laquelle cela ne fonctionne pas à l'aide des paramètres, comme l'a démontré plus tard dans l'exemple lié, est parce que sp_executesql est exécuté dans son propre champ d'application et donc ne peut donc pas voir la portée de la connexion.
[EDIT]
Pour en savoir plus pour le lecteur plus curieux, s'il vous plaît trouver le code VB.NET ci-dessous qui fournit un exemple d'exécuter deux commandes séparées sur une seule connexion, avec la deuxième commande l'émission du SCOPE_IDENTITY sucessfully() fonction.
Le code source peut être exécuté à partir du composant SCRIPT d'une tâche de package SSIS. Vous devrez également modifier les détails de connexion pour votre environnement et également créer l'objet de table référencé.
Créer un script de table:
create table TestTable
(
ID int identity(1,1) primary key not null,
SomeNumericData int not null
);
VB.NET Source Liste:
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
"C'est parce que la portée est maintenue/visible au niveau de la connexion." Je suis en désaccord avec vous .. la portée est déterminée par où vous spécifiez le scope_identity() dans votre requête, dans l'exemple 1 lié, dans 2 requêtes différentes commandes exécutées. puisque les deux sont dans une portée différente, elle renvoie null ... Donc la portée est avec per command seulement .. pas de connexion ... – RameshVel
@Ramesh Vel: Veuillez trouver une modification apportée au message d'origine afin d'inclure le code source qui valide la visibilité de la portée de session sur deux commandes distinctes au sein d'une connexion. –
J'ai fait presque le même genre de test, mais en C# et en exécutant SCOPE_IDENTITY() dans des commandes séparées fonctionne bien même si j'insérais plus d'enregistrements sur la table entre l'appel à insérer et sélectionnez scope_identity() , ReadLine() entre les commandes) – kubal5003