Ist es möglich, eine Tabellenvariable in SQL Server 2008 abzuschneiden oder zu löschen?
Declare @tableVariable table
(
id int,
value varchar(20)
)
while @start<=@stop
begin
insert into @tableVariable(id,value)
select id
, value
from xTable
where id=@start
--Use @tableVariable
--@tableVariable should be flushed out of
-- old values before inserting new values
set @start = @start + 1
end
sql
sql-server
shrekDeep
quelle
quelle
--Use @tableVariable
ich annehme, dass er für einige Berechnungen verwendet wird, die nicht beigefügt sindAntworten:
lösche einfach alles
DELETE FROM @tableVariable
quelle
Nein, Sie können keine
TRUNCATE
Tabellenvariable erstellen, da es sich nicht um eine physische Tabelle handelt. Das Löschen wäre schneller. Siehe diese Antwort von Aaron Bertrand .quelle
TRUNCATE
wäre das sicherlich schneller. Das Löschen aus einer Tabellenvariablen wird imtempdb
Transaktionsprotokoll protokolliert.Ich würde der " technisch " korrekten Antwort hinzufügen
DELETE @VariableTable
, wenn Sie zufällig auch ein Identitätsfeld in Ihrer@Table
Variablen haben (zi int (1,1)
) und diese Tabelle wiederverwenden möchten (auch wenn Sie sie erneut deklarieren eine Schleife) ist immer noch im Geltungsbereich und es gibt auch keine Möglichkeit, sie erneut zu säen.Siehe: Spalte mit der Identität der Tabellenvariablen
Es ist am besten zu verwenden
#TempTable
In diesen Fällen Dann können Sie DBCC zum erneuten Säen abschneiden oder verwenden.Mit Truncate erzielen Sie Leistungsverbesserungen und können zusätzliche Indizes erstellen.
Ich denke , die Faustregel, wenn Sie immer alles gehen löschen verwenden
DELETE @VariableTable
, dann haben Sie einen Code-Geruch eingeführt, der sagt, die Sie verwendet haben sollten#TempTable
undTRUNCATE
stattdessen.quelle
Tabellenvariablen werden nicht unterstützt
TRUNCATE
Syntax. Die einzige Möglichkeit, sie abzuschneiden, besteht darin, sie implizit aus dem Gültigkeitsbereich fallen zu lassen.Sowohl temporäre Tabellen als auch Tabellenvariablen können zwischengespeichert werden, wenn sie in gespeicherten Prozeduren verwendet werden. Im Folgenden wird möglicherweise dieselbe Tabellenvariable nach dem Abschneiden verwendet, anstatt sie tatsächlich zu löschen und zu erstellen
CREATE PROC dbo.foo @start INT AS BEGIN DECLARE @tableVariable TABLE ( id INT, value VARCHAR(20)) INSERT INTO @tableVariable (id, value) SELECT id, value FROM xTable WHERE id = @start; --Use @tableVariable END GO WHILE @start <= @stop BEGIN EXEC dbo.foo @start SET @start = @start + 1 END
Eine weitaus einfachere Alternative wäre natürlich die Umstellung auf a
#temp
Tabelle zu verwenden, da diesTRUNCATE
direkt unterstützt .DML für Tabellenvariablen und temporäre Tabellen schreibt in das
tempdb
Transaktionsprotokoll. Unabhängig davon , ob es lohnt UmschaltungTRUNCATE
statt ,DELETE
hängt von der Größe der betreffenden Daten.TRUNCATE
protokolliert nur die Freigabe der Seite.DELETE
protokolliert die tatsächlich gelöschten Werte. Ein weiterer Unterschied zwischen den beiden besteht darin, dass dieTRUNCATE
Zuordnung der letzten Seite aus der Tabelle aufgehoben wird undDELETE
dies nicht der Fall ist. Wenn in jeder Schleifeniteration nur eine kleine Datenmenge eingefügt und gelöscht wird, kann der Aufwand für die Protokollierung der gelöschten Zeilen geringer sein als der Aufwand für die ständige Freigabe und Neuzuweisung der einzelnen Seite in der Tabelle.Wenn Sie dagegen bei jeder Iteration große Datenmengen einfügen und löschen, werden Sie möglicherweise feststellen, dass
TRUNCATE
das Löschen aller Zeilen nicht nur effizienter ist, sondern auch der nachfolgenden Einfügeanweisung zugute kommt .quelle
DELETE FROM @tableVariable
, wie in der akzeptierten Antwort beschrieben, verwenden, um eine Funktionalität zu erhalten, die im Wesentlichen der entsprichtTRUNCATE TABLE
(mit Ausnahme der Protokollierung - dies könnte sicherlich ein Problem sein, wenn die Variable viele Zeilen enthält oder die SQL, die die Variable erstellt hat, vorhanden ist sehr oft laufen).TRUNCATE
gegenüberDELETE
allen Zeilen ist die Transaktionsprotokollierung.--Usage: exec sp_truncateifexists tablename CREATE PROCEDURE sp_truncateifexists @tableVariable nvarchar(200) AS BEGIN IF EXISTS ( SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tableVariable ) BEGIN DECLARE @query nvarchar(250) SET @query = 'TRUNCATE TABLE ' + @tableVariable EXECUTE (@query) END END GO
Denken Sie daran, # temp-Tabellen zu verwenden , wenn Sie die Tabellen später nicht benötigen.
quelle
Ich weiß, dass dies eine alte Frage ist, aber ich habe einen Weg gefunden, dies zu tun. Wir hatten Tabellen mit Millionen von Zeilen und wollten sie aufgrund des Transaktionsprotokollbereichs nicht löschen.
Erstellen Sie eine Prozedur, die Sie in dem Tabellennamen übergeben, den Sie abschneiden möchten. Die Prozedur erstellt eine andere Prozedur, die die Trukate ausführt, und löscht dann die Prozeduren.
USE [My_Database] GO /****** Object: StoredProcedure [dbo].[ClearOutTable_p1] Script Date: 23/09/2015 09:03:14 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Oraclebhoy -- Create date: 23/09/2015 -- Description: -- -- removes the content of the table passed in through the parameter -- ============================================= create procedure [dbo].[ClearOutTable_p1] @tablename varchar(max) as -- CREATE THE TRUNCATE STATEMENT PASSING IN TABLE VARIABLE declare @truncatesql varchar(max) set @truncatesql = 'truncate table ' + @tablename -- IF PROCEDURE EXISTS DROP if exists (select name from sys.all_objects where name = 'ClearOutTable_TEMP'and type = 'P') begin drop procedure [dbo].[ClearOutTable_TEMP] end -- CREATE TEMP PROCEDURE exec ('create procedure [dbo].[ClearOutTable_TEMP] as '+@truncatesql+'') -- EXECUTE THE PROCEDURE exec [dbo].[ClearOutTable_TEMP] -- DROP THE PROCEDURE drop procedure [dbo].[ClearOutTable_TEMP]
Hoffe das hilft.
quelle