【问题标题】:SQL Server: Delete by selecting value from temp tableSQL Server:通过从临时表中选择值来删除
【发布时间】:2011-12-01 08:06:15
【问题描述】:

我有一个目标表 TBLA 和一个源表 TBLB

第 1 步:我从我的数据库表中获取 SQL:

-- I ran this process in a cursor such that `@Sql` is a pass-in selected column value:
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = 'SELECT TBLB.coloumA, TBLB.coloumB... into ##TempTable
            FROM TBLB 
            WHERE CONVERT(VARCHAR(10),Date,120)='2011-04-05'';

EXEC sp_ExecuteSql @sql

第 2 步:我通过调用另一个 sp_ExecuteSql 来删除目标表数据:

DECLARE @CheckClear NVARCHAR(MAX);
SET @CheckClear = 'DELETE FROM TBLA WHERE EXISTS(SELECT * FROM ##TempTable)';

EXEC sp_ExecuteSql @CheckClear ;
-- This section is where the problem starts, described below.

第 3 步:通过 select * from temp table 插入 TBLA

DECLARE @DumpSql NVARCHAR(MAX);
SET @DumpSql = 'INSERT INTO TBLA 
                SELECT * FROM ##TempTable';

EXEC sp_ExecuteSql @DumpSql ;

如第 2 步末尾所述,问题如下:

执行删除语句后,我发现我的所有数据都丢失了,它似乎只执行了第一个命令(DELETE FROM TBLA)。

在我尝试删除语句之前,我注释掉了 ##TempTable 值,它起作用了,我只有 2011-11-04 的数据。 (TBLA 已经有 2011-11-03 和 2011-11-02 的数据)。

我实际上是按日期值选择数据。到目前为止,它似乎是成功的。

然后,我打开我的TBLA 并看到结果只包含2011-11-04 数据...其余的在哪里?

请注意:

上面的 SQL 只是我使用 sp_executesql 的动态存储产品的一部分... 我的实际数据包含大约 300 个需要处理的表。这些表中的每一个都有不同的唯一身份,所以我不能使用:SELECT * FROM ##Temptable WHERE id=bla

最好的方法是什么?

【问题讨论】:

    标签: sql sql-server tsql temp-tables


    【解决方案1】:

    检查这个: 在 where 条件下使用子查询从 mytable 中删除行:

    DELETE FROM mytable WHERE id IN (SELECT id FROM mytable2)
    

    如果您正在寻找要根据日期删除的唯一值,请在您的临时表中创建唯一值,然后像您一样执行删除操作。

    其次,如果您正在寻找基于联接操作的删除操作: 然后点击此链接:
    How do I delete from multiple tables using INNER JOIN in SQL server

    查看这些链接以了解如何使用 SP_Execute 在临时表中插入行:
    Sql server - how to insert single row into temporary table?
    Insert multiple rows into temp table with one command in SQL2005
    希望这些对您有所帮助..

    【讨论】:

    • 感谢您的回复,但不幸的是,它无法通过 id 识别,因为它是动态应用的方式。和问题有不同类型的表。我在存储产品中运行了这个 sql
    • 请帮忙看看我的问题。希望现在更清楚
    • 我已经更新了一些链接,可以帮助您进一步解决这个问题..
    【解决方案2】:

    首先,您应该确定 TBLA 的主键字段。我假设 PK 是 FLDA。

    当您从临时表中存在的 TBLA 行中删除时,正确的 sintax 是:

    DELETE FROM TBLA
    WHERE FLDA IN 
       (SELECT ##TempTable.FLDA 
       FROM ##TempTable)
    

    使用 sql server 解决这个问题的更优雅的方法是MERGE 语句:

    MERGE 
        INTO  TBLA  AS target
        USING (Select * from ##TempTable)
        ON TBLA.FLDA = ##TempTable.FLDA
        [ WHEN MATCHED [ AND <clause_search_condition> ]
            THEN <merge_matched> ] [ ...n ]
        [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
            THEN <merge_not_matched> ]
        [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
            THEN <merge_matched> ] [ ...n ]
        [ <output_clause> ]
        [ OPTION ( <query_hint> [ ,...n ] ) ] 
    

    已编辑 我看到了你更详细的问题。

    当你执行时:

    DELETE FROM TBLA WHERE EXISTS(SELECT * FROM ##TempTable)
    

    您的所有数据都将被删除,因为 where 条件总是返回 True。

    解决方法可能是连接 TBLA 中的所有表字段,以与连接 ##TempTable 中的所有表字段进行比较。

    【讨论】:

    • 请帮忙看看我的问题。希望现在更清楚
    猜你喜欢
    • 1970-01-01
    • 2013-07-09
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2017-08-17
    相关资源
    最近更新 更多