【问题标题】:ORDER BY causes operand type clashORDER BY 导致操作数类型冲突
【发布时间】:2015-08-11 11:46:18
【问题描述】:

我有一个可以正常工作的存储过程,但我希望向它添加排序。这工作正常:

ALTER PROCEDURE [dbo].[GetAll]
    @SID NVARCHAR(MAX) = NULL,
    @DID NVARCHAR(MAX) = NULL,
    @KID NVARCHAR(MAX) = NULL,
    @name NVARCHAR(MAX) = NULL,
    @sortExpression NVARCHAR(MAX) = NULL,
    @sortDirection NVARCHAR(MAX) = NULL,
    @DateFrom DATETIME = NULL,
    @DateTo DATETIME = NULL

AS
BEGIN
    SET NOCOUNT ON;

    SELECT * FROM [dbo].[MyTable]
    WHERE
        [Message] LIKE CASE WHEN @SID IS NULL THEN [Message] ELSE '%sID=' + @SID + '%' END
    AND
        [Message] LIKE CASE WHEN @DID IS NULL THEN [Message] ELSE '%DID=' + @DID + '%' END
    AND
        [Message] LIKE CASE WHEN @KID IS NULL THEN [Message] ELSE '%CID=' + @KID + '%' END
    AND
        [Message] LIKE CASE WHEN @name IS NULL THEN [Message] ELSE '%name=' + @name + '%' END
    AND
        [Timestamp] BETWEEN ISNULL(@DateFrom, [Timestamp]) AND ISNULL(@DateTo, [Timestamp])
    AND
        [SID] = ISNULL(@SID, [SID])
    AND
        [CID] = ISNULL(@KID, [CID])
END

然后我尝试添加这样的排序:

ALTER PROCEDURE [dbo].[GetAll]
    @SID NVARCHAR(MAX) = NULL,
    @DID NVARCHAR(MAX) = NULL,
    @KID NVARCHAR(MAX) = NULL,
    @name NVARCHAR(MAX) = NULL,
    @sortExpression NVARCHAR(MAX) = NULL,
    @sortDirection NVARCHAR(MAX) = NULL,
    @DateFrom DATETIME = NULL,
    @DateTo DATETIME = NULL

AS
BEGIN
    SET NOCOUNT ON;

    SELECT * FROM [dbo].[MyTable]   -- This is line 24
    WHERE
        [Message] LIKE CASE WHEN @SID IS NULL THEN [Message] ELSE '%sID=' + @SID + '%' END
    AND
        [Message] LIKE CASE WHEN @DID IS NULL THEN [Message] ELSE '%DID=' + @DID + '%' END
    AND
        [Message] LIKE CASE WHEN @KID IS NULL THEN [Message] ELSE '%CID=' + @KID + '%' END
    AND
        [Message] LIKE CASE WHEN @name IS NULL THEN [Message] ELSE '%name=' + @name + '%' END
    AND
        [Timestamp] BETWEEN ISNULL(@DateFrom, [Timestamp]) AND ISNULL(@DateTo, [Timestamp])
    AND
        [SID] = ISNULL(@SID, [SID])
    AND
        [CID] = ISNULL(@KID, [CID])
    ORDER BY
    CASE WHEN @sortDirection = 'asc' THEN
        CASE
            WHEN @sortExpression = 'ID' THEN [ID]
            WHEN @sortExpression = 'Timestamp' THEN [Timestamp]
            WHEN @sortExpression = 'Message' THEN [Message]
            WHEN @sortExpression = 'PID' THEN [PID]
            WHEN @sortExpression = 'CID' THEN [CID]
            WHEN @sortExpression = 'SID' THEN [SID]
            WHEN @sortExpression = 'OType' THEN [OType]
            WHEN @sortExpression = 'OID' THEN [OID]
        END
    END ASC,
    CASE WHEN @sortDirection = 'desc' THEN
        CASE
            WHEN @sortExpression = 'ID' THEN [ID]
            WHEN @sortExpression = 'Timestamp' THEN [Timestamp]
            WHEN @sortExpression = 'Message' THEN [Message]
            WHEN @sortExpression = 'PID' THEN [PID]
            WHEN @sortExpression = 'CID' THEN [CID]
            WHEN @sortExpression = 'SID' THEN [SID]
            WHEN @sortExpression = 'OType' THEN [OType]
            WHEN @sortExpression = 'OID' THEN [OID]
        END
    END DESC
END

这给了我以下错误:

Msg 206, Level 16, State 2, Procedure GetAll, Line 24
Operand type clash: decimal is incompatible with datetime2
Msg 206, Level 16, State 2, Procedure GetAll, Line 24
Operand type clash: ntext is incompatible with datetime2
Msg 206, Level 16, State 2, Procedure GetAll, Line 24
Operand type clash: ntext is incompatible with datetime2
Msg 206, Level 16, State 2, Procedure GetAll, Line 24
Operand type clash: decimal is incompatible with datetime2
Msg 206, Level 16, State 2, Procedure GetAll, Line 24
Operand type clash: uniqueidentifier is incompatible with datetime2

有人知道这是为什么吗?我真的不知道我在这里做错了什么。

附:我的列和参数的命名更恰当,但我已经为这篇文章审查了它们

【问题讨论】:

标签: sql sql-server stored-procedures sql-server-2012


【解决方案1】:

CASE 是一个返回单一类型的表达式。因此,您的类型不兼容。不要试图让它们兼容,而是对每一列使用单独的表达式:

(CASE WHEN @sortDirection = 'asc' AND @sortExpression = 'ID' THEN [ID] END) ASC,
(CASE WHEN @sortDirection = 'asc' AND @sortExpression = 'Timestamp' THEN [Timestamp] END) ASC,
. . .
(CASE WHEN @sortDirection = 'desc' AND @sortExpression = 'OID' THEN [OID] END) DESC

不匹配的条件都返回NULL,所以不影响排序。

另一种选择是使用动态 SQL。

【讨论】:

  • 像魅力一样工作。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多