0

我有一个 SQL Server 过程,我需要将它转换为在 mysql 中工作。

下面是我尝试过的 Mysql 转换过程,但它不完整......

DELIMITER $$

DROP PROCEDURE IF EXISTS `SelectjqGridUsers` $$
CREATE PROCEDURE `SelectjqGridUsers` (IN PageIndex INT,IN SortColumnName VARCHAR(50),IN SortOrderBy VARCHAR(4) ,IN NumberOfRows INT ,OUT TotalRecords INT)

BEGIN

 DECLARE StartRow INT;
 DECLARE CTE VARCHAR(100);

 SELECT  TotalRecords = ( SELECT COUNT(1) FROM  Users );

 SET StartRow = (PageIndex * NumberOfRows ) + 1 ;


END $$

DELIMITER ;

这是我原来的 SQL Server 过程:

CREATE PROC [SelectjqGridUsers]
@PageIndex INT ,
@SortColumnName VARCHAR(50) ,
@SortOrderBy VARCHAR(4) ,
@NumberOfRows INT ,
@TotalRecords INT OUTPUT
AS 
BEGIN

    SET NOCOUNT ON 

    SELECT  @TotalRecords = ( SELECT    COUNT(1)
                              FROM      [Users]
                            )

    DECLARE @StartRow INT
    SET @StartRow = ( @PageIndex * @NumberOfRows ) + 1 ;


    WITH    CTE
              AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY CASE
                                                          WHEN @SortColumnName = 'UserID'
                                                          AND @SortOrderBy = 'asc'
                                                          THEN UserID
                                                         END ASC, CASE
                                                          WHEN @SortColumnName = 'UserID'
                                                          AND @SortOrderBy = 'desc'
                                                          THEN UserID
                                                          END DESC, CASE
                                                          WHEN @SortColumnName = 'UserName'
                                                          AND @SortOrderBy = 'asc'
                                                          THEN UserName
                                                          END ASC, CASE
                                                          WHEN @SortColumnName = 'UserName'
                                                          AND @SortOrderBy = 'desc'
                                                          THEN UserName
                                                          END DESC, CASE
                                                          WHEN @SortColumnName = 'FirstName'
                                                          AND @SortOrderBy = 'asc'
                                                          THEN FirstName
                                                          END ASC, CASE
                                                          WHEN @SortColumnName = 'FirstName'
                                                          AND @SortOrderBy = 'desc'
                                                          THEN FirstName
                                                          END DESC , CASE
                                                          WHEN @SortColumnName = 'MiddleName'
                                                          AND @SortOrderBy = 'asc'
                                                          THEN MiddleName
                                                          END ASC, CASE
                                                          WHEN @SortColumnName = 'MiddleName'
                                                          AND @SortOrderBy = 'desc'
                                                          THEN MiddleName
                                                          END DESC , CASE
                                                          WHEN @SortColumnName = 'LastName'
                                                          AND @SortOrderBy = 'asc'
                                                          THEN LastName
                                                          END ASC, CASE
                                                          WHEN @SortColumnName = 'LastName'
                                                          AND @SortOrderBy = 'desc'
                                                          THEN LastName
                                                          END DESC, CASE
                                                          WHEN @SortColumnName = 'EmailID'
                                                          AND @SortOrderBy = 'asc'
                                                          THEN EmailID
                                                          END ASC, CASE
                                                          WHEN @SortColumnName = 'EmailID'
                                                          AND @SortOrderBy = 'desc'
                                                          THEN EmailID
                                                          END DESC ) AS RN ,
                            UserID ,
                            UserName ,
                            FirstName ,
                            MiddleName ,
                            LastName ,
                            EmailID
                   FROM     [Users]
                 )
        SELECT  UserID ,
                UserName ,
                FirstName ,
                LastName ,
                MiddleName ,
                EmailID
        FROM    CTE
        WHERE   RN BETWEEN @StartRow - @NumberOfRows
                   AND     @StartRow - 1

    SET NOCOUNT OFF


END

谁能帮我完成这个?

4

1 回答 1

1

嗯,一方面,WITH在 MySQL 中没有直接等效的 CTE(语句开头的子句)。也没有确切的替代品ROW_NUMBER()

但是,您可能会理解并(希望)接受这样一个事实,即人类语言中的句子并不总是逐字翻译成另一种语言。同样,用一种 SQL 编写的 SQL 查询可能不会也不必转换为不同的多种子句 for 子句。要翻译查询,您需要两件同样重要的事情:了解查询的作用以及在目标 SQL 种类中的通用性。

您正在翻译的存储过程实现了对特定表的动态排序行的动态分页。

关于分页,SQL Server 没有它的本机语法,就像 MySQL 的LIMIT ... OFFSET ...功能一样。一个可能最典型的解决方法,你也可以在这里看到,是使用ROW_NUMBER()函数和子选择(在这种情况下,子选择恰好采用 CTE 的形式)。这是如何运作的?ROW_NUMBER()根据特定的排序条件为子查询中的每一行分配数字,主查询只是过滤这些数字以获取一系列行,从而有效地为您提供一个页面。

在 MySQL 中你不需要任何类似的东西,仅仅因为它提供了LIMIT ...OFFSET ...,当在存储过程的上下文中使用时,它们都可以接受整数类型的参数或本地整数类型的变量作为它们的参数(嗯,它们可以如果您使用的是 MySQL 5.5.6+ )。

至于动态排序,在 SQL Server 中,排序必须应用于ROW_NUMBER()函数,因为它与动态分页结合使用。但在 MySQL 中,您只需将ROW_NUMBER()'ORDER BY子句直接移动到(主)查询。

因此,最后,这就是我想出的替代SELECT存储过程中查询的方法:

SELECT  UserID ,
        UserName ,
        FirstName ,
        LastName ,
        MiddleName ,
        EmailID

FROM    Users

ORDER BY
        CASE WHEN @SortColumnName = 'UserID'     AND @SortOrderBy = 'asc'  THEN UserID     END ASC,
        CASE WHEN @SortColumnName = 'UserID'     AND @SortOrderBy = 'desc' THEN UserID     END DESC,
        CASE WHEN @SortColumnName = 'UserName'   AND @SortOrderBy = 'asc'  THEN UserName   END ASC,
        CASE WHEN @SortColumnName = 'UserName'   AND @SortOrderBy = 'desc' THEN UserName   END DESC,
        CASE WHEN @SortColumnName = 'FirstName'  AND @SortOrderBy = 'asc'  THEN FirstName  END ASC,
        CASE WHEN @SortColumnName = 'FirstName'  AND @SortOrderBy = 'desc' THEN FirstName  END DESC,
        CASE WHEN @SortColumnName = 'MiddleName' AND @SortOrderBy = 'asc'  THEN MiddleName END ASC,
        CASE WHEN @SortColumnName = 'MiddleName' AND @SortOrderBy = 'desc' THEN MiddleName END DESC,
        CASE WHEN @SortColumnName = 'LastName'   AND @SortOrderBy = 'asc'  THEN LastName   END ASC,
        CASE WHEN @SortColumnName = 'LastName'   AND @SortOrderBy = 'desc' THEN LastName   END DESC,
        CASE WHEN @SortColumnName = 'EmailID'    AND @SortOrderBy = 'asc'  THEN EmailID    END ASC,
        CASE WHEN @SortColumnName = 'EmailID'    AND @SortOrderBy = 'desc' THEN EmailID    END DESC

LIMIT   NumberOfRows
OFFSET  StartRow
;

不过,有一个问题。和 的参数化LIMIT只能OFFSET单个引用(对参数或变量)的形式完成,即您不能在那里使用表达式。所以,我不得不简单地OFFSET StartRow在上面使用。但是,除非您还像这样更改SET StartRow语句,否则它将为您提供与 SQL Server 版本返回的页面不同的页面:

SET StartRow = (PageIndex - 1) * NumberOfRows + 1 ;
于 2013-01-23T09:55:26.807 回答