删除T-SQL中与另一个结果集无关的桥表行

时间:2011-12-01 20:48:49

标签: sql sql-delete jointable

我想写一个删除脚本,删除桥表中的行(acucore_securitypermission)。现在,这个SELECT查询(将是我要删除的行)不起作用。我在包含“NOT EXISTS”的行上显示红色下划线。与第一个和第二个片段的唯一区别是SELECT *与DELETE。此外,如果你有一些改进,我可以删除,以使其更清洁(不重复),我一直在寻找提示。

无效的SELECT脚本:

SELECT groupname
FROM dbo.acucore_securitycontainer
INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
WHERE containername LIKE '%:UI.Web.AccessioningDashboard'
AND groupname NOT EXISTS -- <-------- I get red error underlines here!
(
    SELECT 
        groupname
    FROM dbo.acucore_securitycontainer
    INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
    INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
    WHERE containername = 'UI.Web.AccessioningDashboard'
    AND permissions = 1
)

删除我想要最终运行的脚本:

DELETE FROM dbo.acucore_securitycontainer
INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
WHERE containername LIKE '%:UI.Web.AccessioningDashboard'
AND groupname NOT EXISTS 
(
    SELECT 
        groupname
    FROM dbo.acucore_securitycontainer
    INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
    INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
    WHERE containername = 'UI.Web.AccessioningDashboard'
    AND permissions = 1
)

=====================

UPDATE 12/1/2011 @ 3:05 pm

好的,为了完成此操作,我想从acucore_securitypermission桥表中删除。此表中有两个键。我怎么能完成这个? SELECT查询是包含两个键值的WHERE部分。

DELETE FROM dbo.acucore_securitypermission
 .... ????

SELECT 
    dbo.acucore_securitypermission.entityid,
    dbo.acucore_securitypermission.esid
FROM dbo.acucore_securitycontainer
INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
WHERE containername LIKE '%:UI.Web.AccessioningDashboard'
AND groupname NOT IN
(
    SELECT 
        groupname
    FROM dbo.acucore_securitycontainer
    INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
    INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
    WHERE containername = 'UI.Web.AccessioningDashboard'
    AND permissions = 1
)

==========

最终答案:

DELETE FROM dbo.acucore_securitypermission
WHERE 
    'ENTITYID:' + cast(dbo.acucore_securitypermission.entityid as VARCHAR(64)) + '|' 
    + 'ESID:' + cast(dbo.acucore_securitypermission.esid as VARCHAR(64)) IN
(
    SELECT 
    --groupname,
    --containername,
    --dbo.acucore_securitypermission.esid ,
    --dbo.acucore_securitypermission.entityid ,
    --dbo.acucore_securitypermission.permissions        
        'ENTITYID:' + cast(dbo.acucore_securitypermission.entityid as VARCHAR(64)) + '|' 
        + 'ESID:' + cast(dbo.acucore_securitypermission.esid as VARCHAR(64))
    FROM dbo.acucore_securitypermission
    JOIN dbo.acucore_securitycontainer ON dbo.acucore_securitypermission.esid = dbo.acucore_securitycontainer.esid
    JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
    WHERE containername LIKE 'S:UI.Web.AccessioningDashboard'
    AND groupname NOT IN
    (
        SELECT 
            CASE WHEN groupname IN ('Accessioning', 'Screening', 'Positive Certify', 'Negative Certify', 'Confirmation') THEN 'Saliva: ' + groupname ELSE groupname END
        FROM dbo.acucore_securitypermission
        JOIN dbo.acucore_securitycontainer ON dbo.acucore_securitypermission.esid = dbo.acucore_securitycontainer.esid
        JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
        WHERE containername = 'UI.Web.AccessioningDashboard'
        AND permissions = 1
    )
)

4 个答案:

答案 0 :(得分:1)

尝试使用“NOT IN”而不是“NOT EXISTS”。

编辑12/01/2011 15:24

对于删除,您可以通过将它们转换为varchar然后将它们连接成单个字符串来验证两个键是否存在。这将允许你使“IN”工作。

DELETE FROM dbo.acucore_securitypermission
WHERE cast(entityid as VARCHAR(64)) + '-' + cast(esid as VARCHAR(64)) IN
(
    SELECT cast(entityid as VARCHAR(64)) + '-' + cast(esid as VARCHAR(64))
    FROM dbo.acucore_securitycontainer
    INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
    INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
    WHERE containername LIKE '%:UI.Web.AccessioningDashboard'
    AND groupname NOT IN
    (
        SELECT groupname
        FROM dbo.acucore_securitycontainer
        INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
        INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
        WHERE containername = 'UI.Web.AccessioningDashboard'
        AND permissions = 1
    )
)

像骆驼一样,它很难看,但应该完成工作。

答案 1 :(得分:1)

您只需要在DELETEFROM子句中引用要删除的表格

DELETE FROM dbo.acucore_securitypermission 
FROM   dbo.acucore_securitycontainer 
       INNER JOIN dbo.acucore_securitypermission sp 
         ON dbo.acucore_securitycontainer.esid = sp.esid 
       INNER JOIN dbo.acucore_securitygroup 
         ON sp.entityid = dbo.acucore_securitygroup.entityid 
WHERE  containername LIKE '%:UI.Web.AccessioningDashboard' 
       AND groupname NOT IN (SELECT groupname 
                             FROM   dbo.acucore_securitycontainer 
                                    INNER JOIN dbo.acucore_securitypermission 
                                      ON dbo.acucore_securitycontainer.esid = 
                                         dbo.acucore_securitypermission.esid 
                                    INNER JOIN dbo.acucore_securitygroup 
                                      ON dbo.acucore_securitypermission.entityid 
                              WHERE containername = 'UI.Web.AccessioningDashboard'
                                    AND permissions = 1)

这是特定于SQL Server的文档DELETE (Transact-SQL)

  

FROM <table_source>

     

指定其他FROM子句。这个DELETE的Transact-SQL扩展      允许从<table_source>指定数据并删除相应的行      来自第一个FROM子句中的表。

     

可以使用此扩展指定连接,而不是子查询      在WHERE子句中标识要删除的行。

如果您真的必须将其作为子查询执行,则可以使用EXISTS

DELETE FROM dbo.acucore_securitypermission 
WHERE EXISTS
(
    SELEC *
    FROM dbo.acucore_securitycontainer
    INNER JOIN dbo.acucore_securitypermission sp ON dbo.acucore_securitycontainer.esid = sp.esid
    INNER JOIN dbo.acucore_securitygroup ON dbsp.entityid = dbo.acucore_securitygroup.entityid
    WHERE containername LIKE '%:UI.Web.AccessioningDashboard'
    AND groupname NOT IN
    (
        SELECT groupname
        FROM dbo.acucore_securitycontainer
        INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
        INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
        WHERE containername = 'UI.Web.AccessioningDashboard'
        AND permissions = 1
    )
   AND dbo.acucore_securitypermission.entityid  = sp.entityid 
     and dbo.acucore_securitypermission.esid = sp.esid 
)

答案 2 :(得分:0)

像这样:

SELECT groupname
FROM dbo.acucore_securitycontainer
INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
WHERE containername LIKE '%:UI.Web.AccessioningDashboard'
AND groupname NOT IN -- <-------- Replace exists by IN!
(
    SELECT 
        groupname
    FROM dbo.acucore_securitycontainer
    INNER JOIN dbo.acucore_securitypermission ON dbo.acucore_securitycontainer.esid = dbo.acucore_securitypermission.esid
    INNER JOIN dbo.acucore_securitygroup ON dbo.acucore_securitypermission.entityid = dbo.acucore_securitygroup.entityid
    WHERE containername = 'UI.Web.AccessioningDashboard'
    AND permissions = 1
)

答案 3 :(得分:0)

NOT EXISTS更改为NOT IN