使用WITH的SQL Server内部联接(NOLOCK)

时间:2015-12-03 12:07:30

标签: sql sql-server join inner-join self-join

我有一个数据库查询:

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;

所以,我的查询看起来很正确。

此外,当我删除BR WITH (NOLOCK)旁边的WITH(NOLOCK),即我的内连接查询时,查询运行正常。关于我可能缺少的任何想法??

PS:我的数据库兼容级别为110。

5 个答案:

答案 0 :(得分:5)

您将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 :(得分:2)

刚刚放

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
在查询之前

。 NOLOCK行为将用于查询中的所有表。使用提示NOLOCK只意味着对特定表使用READ UNCOMMITTED事务隔离级别。

答案 2 :(得分:1)

错误是GROUP BY子句中有WITH (NOLOCK)的地方,当它应该只在FROM子句中时:

 GROUP BY Table1_id) as  BR WITH (NOLOCK)

应该是

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;

答案 3 :(得分: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;

答案 4 :(得分: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

试试......