0

我有一个使用临时表的存储过程。问题是我尝试在不同的SELECT INTO语句中多次使用临时表。当然,在发布下一个声明之前我已经发布了一个DROP #TempTableName然后发布SELECT INTO声明。显然这个DROP语句是不够的,因为下一个SELECT INTO语句抱怨对象#TempTableName已经存在 - SSMS 输出是:

消息 2714,级别 16,状态 1,过程 SYNC_SpreadMembers,第 23 行
数据库中已经有一个名为“#MM_SYNC_MEMBERS”的对象。

这是我的 T-SQL 代码:

CREATE PROCEDURE SYNC_SpreadMembers
AS
BEGIN
    BEGIN

        -- Member
        IF (OBJECT_ID('tempdb..#MM_SYNC_MEMBERS') IS NOT NULL) 
            DROP TABLE #MM_SYNC_MEMBERS;
        -- Imported members
        SELECT DISTINCT MemberInr INTO #MM_SYNC_MEMBERS FROM
            (
                SELECT DISTINCT DmInr AS MemberInr FROM MM_SYNC_EBOLIGWS WHERE NOT DmInr IS NULL
                UNION 
                SELECT DISTINCT AmInr AS MemberInr FROM MM_SYNC_EBOLIGWS WHERE NOT AmInr IS NULL
            ) MemberHeap
        ;                   
        DELETE #MM_SYNC_MEMBERS FROM #MM_SYNC_MEMBERS Sync INNER JOIN MM_Member Member ON Sync.MemberInr = Member.InteressentNr;
        INSERT INTO MM_Member(InteressentNr) SELECT MemberInr FROM #MM_SYNC_MEMBERS;
    END

    -- Hardcoded members
    DROP TABLE #MM_SYNC_MEMBERS;
    SELECT DISTINCT InteressentNr AS MemberInr INTO #MM_SYNC_MEMBERS FROM MM_SYNC_HardcodedMemberRoles;
    DELETE #MM_SYNC_MEMBERS FROM #MM_SYNC_MEMBERS Sync INNER JOIN MM_Member Member ON Sync.MemberInr = Member.InteressentNr;
    INSERT INTO MM_Member(InteressentNr) SELECT MemberInr FROM #MM_SYNC_MEMBERS;

    -- MemberRole
    -- Area Managers
    DELETE MM_MemberRole;
    INSERT INTO MM_MemberRole(MemberSid, RoleSid)
        SELECT DISTINCT Member.[Sid], (SELECT [Sid] FROM MM_Role WHERE Cipher LIKE 'AMA')
        FROM MM_SYNC_EBOLIGWS Sync
            INNER JOIN MM_Member Member ON Sync.AmInr = Member.InteressentNr
        WHERE Sync.AmInr IS NOT NULL
    ;
    -- Department Managers
    INSERT INTO MM_MemberRole(MemberSid, RoleSid)
        SELECT DISTINCT Member.[Sid], (SELECT Sid FROM MM_Role WHERE Cipher LIKE 'DM')
        FROM MM_SYNC_EBOLIGWS Sync
            INNER JOIN MM_Member Member ON Sync.DmInr = Member.InteressentNr
        WHERE Sync.DmInr IS NOT NULL
    ;

    -- Hardcoded Roles
    INSERT INTO MM_MemberRole(MemberSid, RoleSid)
        SELECT Member.Sid, Roles.Sid 
        FROM MM_SYNC_HardcodedMemberRoles HCR 
            INNER JOIN MM_Member Member ON HCR.InteressentNr = Member.InteressentNr
            INNER JOIN MM_Role Roles ON HCR.RoleCipher = Roles.Cipher
    ;
END
GO
4

4 回答 4

2

T-SQL 是一种非常简单的语言——它基本上会尽快编译当前作用域/批处理中的所有代码。在不同的时间(例如创建新表时),它将重新编译批处理。

在您首次创建新临时表后立即重新编译时,实际上会引发错误。那时,当它试图重新编译后面的语句时,它也试图创建一个同名的临时表,它会产生错误。

它不会等待查看正常的执行流程(包括控制流程)是否会防止到达语句时发生错误。例如,这会产生类似的错误:

create table #Blah (ID int)
if 1 = 0
begin
    create table #Blah (Foo int)
end

即使我们可以看到它并知道实际上不会发生任何伤害

消息 2714,第 16 层,状态 1,第 4 行

数据库中已经有一个名为“#Blah”的对象。

于 2013-05-23T07:35:11.193 回答
0

临时表绑定到一个连接。所以当连接被删除时,临时表也被删除。

所以它不会在存储过程的中间被丢弃。

这将与它所在的实例相关联,它可以满足您的需求:

DECLARE @TemporaryTable TABLE 
(
      id int,
      name nvarchar(50)
)

额外: 也许你也可以看看 CTE,因为它可能是你问题的解决方案:http: //msdn.microsoft.com/en-us/library/ms190766 (v=sql.105).aspx

于 2013-05-22T20:57:33.247 回答
0

由于表在两个插入中具有相同的列,为什么不只创建一次表,而不是删除它:

 TRUNCATE TABLE #MM_SYNC_MEMBERS
于 2013-05-22T20:31:57.077 回答
0

为什么要全局创建#MM_SYNC_MEMBERS 结构,然后可以根据条件在temp 中删除或插入数据。

前任-

创建表#Temp(名称varchar(20))


IF(条件1)插入临时(或删除)否则如果(条件2)插入临时......

于 2017-09-28T05:17:52.503 回答