0

原文标题:为什么在 T-SQL 的比较中使用像“{Bad”这样的值会影响结果?

我创建了一个存储过程来处理大表的分页。该过程的重要部分如下:

DECLARE @first_id NVARCHAR(250);
DECLARE @first_parent NVARCHAR(250);

SET @skip = @skip + 1

SELECT TOP(@skip) @first_id = id,
                  @first_parent = parent
FROM   [dbo].[DATA]
WHERE  RowSet = @rowset
       AND FieldID = @field_id
       AND ( parent = @parent
              OR @parent IS NULL )
ORDER  BY parent,
          id;

SELECT TOP(@max) id,
                 [Description],
                 Closed,
                 Hold,
                 Access,
                 [Type],
                 parent
FROM   [dbo].[DATA]
WHERE  parent >= @first_parent
       AND id >= @first_id
       AND RowSet = @rowset
       AND FieldID = @field_id
       AND ( parent = @parent
              OR @parent IS NULL )
ORDER  BY parent,
          id 

它工作正常,除非@first_parent 是'{Problem',当这种情况发生时结果中的一半行被跳过。是'{'吗?这是在 SQL Server 2008 R2 上运行的。

4

1 回答 1

0

感谢 Martin Smith 让我找出解决这个问题的最低限度。该问题与“{”或任何其他字符无关。问题是尝试使用 TOP 来分页,其中 2 列用于选择起始行。

为了强调为什么使用两列不起作用,请以下表为例

-----------------------
| Parent       |   Id |
|--------------|------|
| 1            |   1  |
| 1            |   2  |
| 1            |   3  |
| 2            |   1  |
| 2            |   2  |
| 2            |   3  |
| 3            |   1  |
| 3            |   2  |
| 3            |   3  |
-----------------------

你运行上面的存储过程,最终的选择,填充数据而不是变量,将是:

SELECT TOP(@max) id,
             [Description],
             Closed,
             Hold,
             Access,
             [Type],
             parent
FROM   [dbo].[DATA]
WHERE  parent >= '1'
   AND id >= '2'
   AND RowSet = @rowset
   AND FieldID = @field_id
   AND ( parent = @parent
          OR @parent IS NULL )
ORDER  BY parent,
      id 

当您查看时,很明显为什么没有返回所有预期结果。所以道德是,如果您尝试使用 SET ROWCOUNT/TOP 分页方法,您只能使用一列来选择起始行。

更新:2013-3-12

经过进一步的研究/努力,事实证明,如果您可以将列视为一列,则可以使用分页的 TOP/SET ROWCOUNT 方法,如下所示:

DECLARE @startat NVARCHAR(500)
SELECT TOP(@skip) @startat = COLUMN1 + <separator> + COLUMN2 + <separator> +... + COLUMNN
  FROM <TABLE>
  WHERE <WHATEVER YOU NEED> -- Optional
  ORDER BY COLUMN1, COLUMN2, ... COLUMNN

SELECT TOP(@max) <columns you want>
    WHERE <WHATEVER YOU NEED> AND COLUMN1 + <separator> + COLUMN2 + <separator> +... + COLUMNN >= @startat
    ORDER BY COLUMN1, COLUMN2, ... COLUMNN

@skip 和 @max 是您的分页参数。

分隔符应该是小于数据中任何允许的字符的字符,对我来说 CHAR(13) 效果很好。它是必需的,否则您最终会遇到上述问题。

另请注意,这要求所有列都是文本或可转换为文本。如果您的列允许 NULL 值,我建议使用 COALESCE(COLUMN, N'')。

于 2013-03-08T21:40:33.547 回答