Удалите строки таблицы моста в T-SQL, которые не относятся к другому набору результатов - PullRequest
1 голос
/ 02 декабря 2011

Я хотел бы написать скрипт удаления, который удаляет строки из таблицы мостов (acucore_securitypermission). Прямо сейчас этот запрос SELECT (это будут строки, которые я хотел бы удалить) не работает. Я получаю красные подчеркивания на строке, содержащей «НЕ СУЩЕСТВУЕТ». Единственное отличие от первого и второго фрагмента - это 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
)

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

ОБНОВЛЕНИЕ 12/1/2011 @ 15: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 ]

1 голос
/ 02 декабря 2011

Вам просто нужно сослаться на таблицу, которую вы хотите удалить, в предложениях DELETE и FROM

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 из документов УДАЛИТЬ (Transact-SQL)

ОТ <table_source>

Определяет дополнительное предложение FROM. Это расширение 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 
)
1 голос
/ 02 декабря 2011

Попробуйте использовать «NOT IN» вместо «NOT EXISTS».

Редактировать 12/01/2011 15:24

Для удаления вы можете проверить наличие обоих ключей с помощьюпреобразование их в varchar и затем объединение их в одну строку.Это позволило бы вам заставить работать «В».

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
    )
)

Как верблюд, это безобразно, но оно должно выполнить работу.

0 голосов
/ 02 декабря 2011

Изменить NOT EXISTS на NOT IN

0 голосов
/ 02 декабря 2011

Как это:

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
)
...