webentwicklung-frage-antwort-db.com.de

Führen Sie sp_executeSql für select ... in #table aus, aber Temp-Tabellendaten können nicht ausgewählt werden

Versuchte, ... in eine temporäre Tabelle #TempTable in sp_Executedsql auszuwählen. Nicht seine erfolgreich eingefügt oder nicht, aber dort Nachrichten geschrieben (359 Zeile (n) betroffen), die bedeuten, erfolgreich eingefügt? Skript unten

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;

Nach der Ausführung gibt es mich auf Nachrichten zurück (359 betroffene Zeile (n)). Weiter, wenn Sie versuchen, die Daten aus #TempTable auszuwählen.

Select * From #TempTable;

Es gibt mir zurück:

Msg 208, Level 16, State 0, Line 2
Invalid object name '#TempTable'.

Es wird vermutet, dass nur der 'select'-Bereich funktioniert. Der Einsatz funktioniert nicht. Wie kann ich das beheben?

33
Worgon

Lokale temporäre Tabelle #table_name ist nur in der aktuellen Sitzung sichtbar, global temporär ##table_name Tabellen sind in allen Sitzungen sichtbar. Beide leben, bis ihre Sitzung geschlossen ist. sp_executesql - erstellt eine eigene Sitzung (vielleicht ist Word "scope" besser), deshalb passiert es.

28
Michał Powaga

Die Verwendung einer globalen temporären Tabelle in diesem Szenario kann zu Problemen führen, da die Tabelle zwischen Sitzungen vorhanden ist und möglicherweise zu Problemen bei der asynchronen Verwendung des aufrufenden Codes führt.

Eine lokale temporäre Tabelle kann verwendet werden, wenn sie vor dem Aufruf von sp_executesql definiert wurde, z.

CREATE TABLE #tempTable(id int);

sp_executesql 'INSERT INTO #tempTable SELECT myId FROM myTable';

SELECT * FROM #tempTable;
38
Rob Willis

Fügen Sie in Ihre Zeichenfolge @sql Nicht into #TempTable Ein. Rufen Sie stattdessen Ihre SELECT -Anweisung ohne eine INSERT -Anweisung auf.

Fügen Sie abschließend die Ergebnisse wie folgt in Ihre temporäre Tabelle ein:

INSERT INTO @tmpTbl EXEC sp_executesql @sql

Außerdem müssen Sie die temporäre Tabelle deklarieren, wenn Sie diesen Ansatz verwenden

DECLARE @tmpTbl TABLE (
    //define columns here...
)
11
Mark Entingh

ihre temporäre Tabelle in dynamischem SQL liegt im nicht dynamischen SQL-Teil außerhalb des gültigen Bereichs.

Sehen Sie hier, wie Sie damit umgehen: Ein bisschen über die lokalen temporären Tabellen von SQL Server

7
Mladen Prajdic

Temporäre Tabellen sind nur so lange gültig wie die Verbindung, die sie erstellt. Ich würde erwarten, dass Sie die Auswahl unbeabsichtigt auf einer separaten Verbindung ausstellen. Sie können dies testen, indem Sie Ihre Einfügung vorübergehend in eine nicht temporäre Tabelle einfügen und prüfen, ob Ihre Daten vorhanden sind. In diesem Fall können Sie zu Ihrer ursprünglichen Lösung zurückkehren und das Verbindungsobjekt nur an Ihre Auswahl übergeben.

3
Carth

Das hat bei mir funktioniert

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
1
WebBoy

Um dieses Problem zu umgehen, verwenden Sie zuerst den Befehl CREATE TABLE #TEMPTABLE, um eine leere temporäre Tabelle zu generieren, bevor Sie sp_executesql ausführen. Führen Sie dann das INSERT INTO #TEMPTABLE mit sp_executesql aus. Das wird funktionieren. So überwinde ich dieses Problem, da ich ein Setup habe, in dem alle meine Abfragen normalerweise über sp_executesql ausgeführt werden.

1
Simon Darlow
declare @sql varchar(1000)
set @sql="select * into #t from table;"
set @sql [email protected] + "select * from #t;"

 execute  SP_EXECUTESQL  @sql