2015-12-03 6 views
1

У меня есть запрос к базе данных:SQL Server Inner Join Using С (NOLOCK)

DECLARE @Pager_PageNumber AS INT, @Pager_PageSize AS INT; 

SET @Pager_PageNumber = 1; 
SET @Pager_PageSize = 12; 

SELECT 
    [Name], [Description], [Table1ID], [VersionNo], [Status] 
FROM 
    (SELECT 
     CAST(Table1.name AS VARCHAR(MAX)) As [Name], 
     CAST(Table1.description AS VARCHAR(MAX)) AS [Description], 
     CAST(CAST(Table1.Table1_ID AS DECIMAL(18,0)) AS VARCHAR(MAX)) AS [Table1ID], 
     CAST(CAST(Table1.VERSION_NO AS DECIMAL(18,0)) AS VARCHAR(MAX)) AS [VersionNo], 
     CAST(Table2.br_status AS VARCHAR(MAX)) AS [Status] 
    FROM 
     Table1 WITH (NOLOCK) 
    INNER JOIN 
     (SELECT 
      Table1_id, MAX(version_no) as version_no 
     FROM Table1 
     WHERE Table1.status = '00002' 
     GROUP BY Table1_id) AS BR WITH (NOLOCK) ON Table1.Table1_id = BR.Table1_id 
               AND BR.version_no = Table1.version_no 
    INNER JOIN 
     Table2 WITH (NOLOCK) ON Table1.status = Table2.br_status_code) A 
ORDER BY 
    [Name], [Description], [Table1ID], [VersionNo], [Status] 
    OFFSET ((@Pager_PageNumber - 1) * @Pager_PageSize) ROWS 
     FETCH NEXT @Pager_PageSize ROWS ONLY; 

SELECT COUNT(*) 
FROM 
    (SELECT 
     CAST(Table1.name AS VARCHAR(MAX)) AS [Name], 
     CAST(Table1.description AS VARCHAR(MAX)) AS [Description], 
     CAST(CAST(Table1.Table1_ID AS DECIMAL(18,0)) AS VARCHAR(MAX)) AS [Table1ID], 
     CAST(CAST(Table1.VERSION_NO AS DECIMAL(18,0)) AS VARCHAR(MAX)) As [VersionNo], 
     CAST(Table2.br_status AS VARCHAR(MAX)) AS [Status] 
    FROM 
     Table1 WITH (NOLOCK) 
    INNER JOIN 
     (SELECT Table1_id, MAX(version_no) as version_no 
     FROM Table1 
     WHERE Table1.status = '00002' 
     GROUP BY Table1_id) AS BR WITH (NOLOCK) ON Table1.Table1_id = BR.Table1_id 
               AND BR.version_no = Table1.version_no 
    INNER JOIN 
     Table2 WITH (NOLOCK) ON Table1.status = Table2.br_status_code) A; 

В SQL Server я получаю ошибку рядом: BR WITH (NOLOCK) что:

Неправильный синтаксис около ключевого слова 'С'. Неверный синтаксис рядом с ключевым словом 'with'. Если этот оператор является общим табличным выражением, предложением xmlnamespaces или предложением контекста отслеживания изменений, предыдущий оператор должен быть прерван точкой с запятой.

Но в моем понимании от источников like синтаксис как

SELECT 
    first_name, last_name, 
FROM 
    dbo.person p WITH (NOLOCK) 
JOIN 
    dbo.employee e WITH (NOLOCK) ON e.person_id = p.person_id 
WHERE 
    p.person_id = 1; 

Итак, мой запрос выглядит примерно правильно.

Кроме того, когда я удаляю WITH (NOLOCK) рядом с BR WITH (NOLOCK), то есть мой внутренний запрос соединения, запрос выполняется нормально. Любые идеи о том, что я могу пропустить?

PS: Мой уровень совместимости DB 110.

+0

отформатируйте свой запрос перед публикацией - http://www.sql-format.com/ – Devart

+0

Отформатирует его. –

+1

Установить [Плохие привычки пинать NOLOCK повсюду] (http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/) - это НЕ РЕКОМЕНДУЕТСЯ *** использовать это везде - наоборот! –

ответ

3

Вы применяете with (nolock) в таблицы, не подзапросов. Таким образом, вместо того, чтобы:

(SELECT Table1_id, MAX(version_no) as version_no 
FROM Table1 
where Table1.status='00002' 
GROUP BY Table1_id 
) as BR WITH (NOLOCK) 

Вы бы написать:

(SELECT Table1_id, MAX(version_no) as version_no 
FROM Table1 WITH (NOLOCK) 
where Table1.status='00002' 
GROUP BY Table1_id 
) BR 
1

Ошибка, где вы должны WITH (NOLOCK) в GROUP BY предложения, когда он должен быть только в ЕКЕ:

GROUP BY Table1_id) as BR WITH (NOLOCK) 

должны be

FROM Table1 WITH (NOLOCK) 

Это 3 строки от нижней части вашего опубликованного кода. Это также проявляется и дальше.

Ваш код с исправлениями (я думаю, что я получил их всех!):

DECLARE @Pager_PageNumber AS INT, @Pager_PageSize AS INT; SET @Pager_PageNumber = 1; SET @Pager_PageSize = 12; SELECT [Name],[Description],[Table1ID],[VersionNo],[Status] FROM(SELECT CAST(Table1.name AS VARCHAR(MAX)) As [Name],CAST(Table1.description AS VARCHAR(MAX)) As [Description],CAST(CAST(Table1.Table1_ID AS DECIMAL(18,0)) AS VARCHAR(MAX)) As 
[Table1ID],CAST(CAST(Table1.VERSION_NO AS DECIMAL(18,0)) AS VARCHAR(MAX)) As [VersionNo], 
CAST(Table2.br_status AS VARCHAR(MAX)) As [Status] FROM Table1 WITH (NOLOCK) 
    INNER JOIN (SELECT Table1_id, MAX(version_no) as version_no 
    FROM Table1 WITH (NOLOCK) 
    where Table1.status='00002' 
    GROUP BY Table1_id) as BR ON Table1.Table1_id = BR.Table1_id AND BR.version_no=Table1.version_no 
    INNER JOIN Table2 WITH (NOLOCK) ON Table1.status = Table2.br_status_code)A 
    ORDER BY [Name],[Description],[Table1ID],[VersionNo],[Status] OFFSET ((@Pager_PageNumber - 1) * @Pager_PageSize) 
    ROWS FETCH NEXT @Pager_PageSize ROWS ONLY;SELECT COUNT(*) FROM(SELECT CAST(Table1.name AS VARCHAR(MAX)) As 
    [Name],CAST(Table1.description AS VARCHAR(MAX)) As [Description],CAST(CAST(Table1.Table1_ID AS DECIMAL(18,0)) 
    AS VARCHAR(MAX)) As [Table1ID],CAST(CAST(Table1.VERSION_NO AS DECIMAL(18,0)) AS VARCHAR(MAX)) As [VersionNo], 
    CAST(Table2.br_status AS VARCHAR(MAX)) As [Status] FROM Table1 WITH (NOLOCK) INNER JOIN 
     (SELECT Table1_id, MAX(version_no) as version_no 
    FROM Table1 WITH (NOLOCK) 
    where Table1.status='00002' 
    GROUP BY Table1_id) as BR 
    ON Table1.Table1_id = BR.Table1_id AND BR.version_no=Table1.version_no INNER JOIN Table2 
    WITH (NOLOCK) ON Table1.status = Table2.br_status_code)A; 
1

Вы можете не перемещать WITH (NOLOCK), так что внутри подзапроса?

По существу, это ...

INNER JOIN (SELECT Table1_id 
             ,MAX(version_no) AS version_no 
           FROM Table1 WITH (NOLOCK) 
           WHERE Table1.status = '00002' 
           GROUP BY Table1_id 
           ) AS BR 

Полный код

DECLARE @Pager_PageNumber AS INT 
    ,@Pager_PageSize AS INT; 
SET @Pager_PageNumber = 1; 
SET @Pager_PageSize = 12; 
SELECT [Name] 
     ,[Description] 
     ,[Table1ID] 
     ,[VersionNo] 
     ,[Status] 
FROM (SELECT CAST(Table1.name AS VARCHAR(MAX)) AS [Name] 
        ,CAST(Table1.description AS VARCHAR(MAX)) AS [Description] 
        ,CAST(CAST(Table1.Table1_ID AS DECIMAL(18, 0)) AS VARCHAR(MAX)) AS [Table1ID] 
        ,CAST(CAST(Table1.VERSION_NO AS DECIMAL(18, 0)) AS VARCHAR(MAX)) AS [VersionNo] 
        ,CAST(Table2.br_status AS VARCHAR(MAX)) AS [Status] 
      FROM  Table1 WITH (NOLOCK) 
        INNER JOIN (SELECT Table1_id 
             ,MAX(version_no) AS version_no 
           FROM Table1 WITH (NOLOCK) 
           WHERE Table1.status = '00002' 
           GROUP BY Table1_id 
           ) AS BR ON Table1.Table1_id = BR.Table1_id 
              AND BR.version_no = Table1.version_no 
        INNER JOIN Table2 WITH (NOLOCK) ON Table1.status = Table2.br_status_code 
     ) A 
ORDER BY [Name] 
     ,[Description] 
     ,[Table1ID] 
     ,[VersionNo] 
     ,[Status] 
     OFFSET ((@Pager_PageNumber - 1) * @Pager_PageSize) ROWS FETCH NEXT @Pager_PageSize 
     ROWS ONLY; 
SELECT COUNT(*) 
FROM (SELECT CAST(Table1.name AS VARCHAR(MAX)) AS [Name] 
        ,CAST(Table1.description AS VARCHAR(MAX)) AS [Description] 
        ,CAST(CAST(Table1.Table1_ID AS DECIMAL(18, 0)) AS VARCHAR(MAX)) AS [Table1ID] 
        ,CAST(CAST(Table1.VERSION_NO AS DECIMAL(18, 0)) AS VARCHAR(MAX)) AS [VersionNo] 
        ,CAST(Table2.br_status AS VARCHAR(MAX)) AS [Status] 
      FROM  Table1 WITH (NOLOCK) 
        INNER JOIN (SELECT Table1_id 
             ,MAX(version_no) AS version_no 
           FROM Table1 WITH (NOLOCK) 
           WHERE Table1.status = '00002' 
           GROUP BY Table1_id 
           ) AS BR ON Table1.Table1_id = BR.Table1_id 
              AND BR.version_no = Table1.version_no 
        INNER JOIN Table2 WITH (NOLOCK) ON Table1.status = Table2.br_status_code 
     ) A; 
1
DECLARE @Pager_PageNumber AS INT, 
     @Pager_PageSize AS INT; 

SELECT @Pager_PageNumber = 1, @Pager_PageSize = 12; 

SELECT [Name],[Description],[BRMAINID],[VersionNo],[Status] 
FROM (
    SELECT 
     Table1.name As [Name], 
     Table1.[description] As [Description], 
     Table1.Table1_ID AS [BRMAINID], 
     Table1.VERSION_NO AS [VersionNo], 
     Table2.br_status AS [Status] 
    FROM dbo.Table1 WITH(NOLOCK) 
    JOIN (
     SELECT Table1_id, MAX(version_no) as version_no 
     FROM dbo.Table1 WITH(NOLOCK) 
     WHERE Table1.[status] = '00002' 
     GROUP BY Table1_id 
    ) AS BR ON Table1.Table1_id = BR.Table1_id AND BR.version_no=Table1.version_no 
    JOIN dbo.Table2 WITH(NOLOCK) ON Table1.status = Table2.br_status_code 
) A 
ORDER BY [Name], [Description], [BRMAINID], [VersionNo], [Status] 
    OFFSET ((@Pager_PageNumber - 1) * @Pager_PageSize) 
    ROWS FETCH NEXT @Pager_PageSize ROWS ONLY 

SELECT COUNT(*) 
FROM dbo.Table1 WITH(NOLOCK) 
JOIN (
    SELECT Table1_id, MAX(version_no) as version_no 
    FROM dbo.Table1 WITH(NOLOCK) 
    where Table1.[status] = '00002' 
    GROUP BY Table1_id 
) as BR ON Table1.Table1_id = BR.Table1_id AND BR.version_no=Table1.version_no 
JOIN dbo.Table2 WITH(NOLOCK) ON Table1.status = Table2.br_status_code 

просто попробовать ...

2

Просто поместите

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

до вашего запроса.Поведение NOLOCK будет использоваться для всех ваших таблиц в запросе. Использование подсказки NOLOCK просто означает использование READ UNCOMMITTED уровня изоляции транзакций для конкретной таблицы.

+0

товарищ, рад вас видеть;) – Devart

+0

О, хорошо, теперь у меня достаточно репутации, чтобы комментировать сообщения :) Привет :) –