J'essayais de sélectionner ... dans une table temporaire #TempTable dans sp_Executedsql. Ce n'est pas inséré avec succès ou pas, mais il y a des messages écrits (359 lignes affectées) qui signifient que l'insertion a réussi? Script ci-dessous
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = 'select distinct Coloum1,Coloum2 into #TempTable
from SPCTable with(nolock)
where Convert(varchar(10), Date_Tm, 120) Between @Date_From And @Date_To';
SET @Sql = 'DECLARE @Date_From VARCHAR(10);
DECLARE @Date_To VARCHAR(10);
SET @Date_From = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
SET @Date_To = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
'+ @Sql;
EXECUTE sp_executesql @Sql;
Une fois exécuté, il me renvoie des messages (359 ligne (s) affectée (s)). Ensuite lorsque vous essayez de sélectionner les données de #TempTable.
Select * From #TempTable;
Son retour me:
Msg 208, Level 16, State 0, Line 2
Invalid object name '#TempTable'.
Suspecté son fonctionnement uniquement la section "sélectionner" uniquement. L'insert ne fonctionne pas. comment y remédier?
Table temporaire locale #table_name
est visible uniquement dans la session en cours, global temporaire ##table_name
les tables sont visibles dans toutes les sessions. Les deux vivent jusqu'à la clôture de leur session. sp_executesql
- crée sa propre session (peut-être que Word "scope" serait mieux), c'est pourquoi cela se produit.
L'utilisation d'une table temporaire globale dans ce scénario peut provoquer des problèmes car la table existe entre les sessions et peut entraîner certains problèmes d'utilisation asynchrone du code appelant.
Une table temporaire locale peut être utilisée si elle est définie avant d'appeler sp_executesql, par ex.
CREATE TABLE #tempTable(id int);
sp_executesql 'INSERT INTO #tempTable SELECT myId FROM myTable';
SELECT * FROM #tempTable;
Dans votre @sql
chaîne, n'insérez pas into #TempTable
. Appelez plutôt votre instruction SELECT
sans instruction INSERT
.
Enfin, insérez les résultats dans votre table temporaire comme suit:
INSERT INTO @tmpTbl EXEC sp_executesql @sql
En outre, vous devrez déclarer la table temporaire si vous utilisez cette approche
DECLARE @tmpTbl TABLE (
//define columns here...
)
votre table temporaire en SQL dynamique est hors de portée dans la partie SQL non dynamique.
Regardez ici comment gérer cela: n peu sur les tables temporaires locales du serveur SQL
Les tables temporaires ne vivent que le temps de la connexion qui les crée. Je m'attendrais à ce que vous émettez involontairement la sélection sur une connexion distincte. Vous pouvez tester cela en faisant momentanément votre insertion dans une table non temporaire et en voyant si vos données sont là. Si tel est le cas, vous pouvez revenir à votre solution d'origine et assurez-vous simplement de passer l'objet de connexion à votre sélection.
Cela a fonctionné pour moi
declare @sql nvarchar(max)
create table #temp ( listId int, Name nvarchar(200))
set @sql = 'SELECT top 10 ListId, Name FROM [V12-ListSelector].[dbo].[List]'
insert into #temp
exec sp_executesql @sql
select * from #temp
drop table #temp
Pour contourner ce problème, utilisez d'abord une commande CREATE TABLE #TEMPTABLE pour générer une table temporaire vide avant d'exécuter sp_executesql. Exécutez ensuite INSERT INTO #TEMPTABLE avec sp_executesql. Cela fonctionnera. C'est ainsi que je surmonte ce problème car j'ai une configuration dans laquelle toutes mes requêtes sont généralement exécutées via sp_executesql.
declare @sql varchar(1000)
set @sql="select * into #t from table;"
set @sql =@sql + "select * from #t;"
execute SP_EXECUTESQL @sql