我有一个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
有人可以帮我完成这个吗?
答案 0 :(得分:1)
嗯,首先,在MySQL中没有直接等效的CTE(语句开头的WITH
子句)。也没有确切替代ROW_NUMBER()
。
但是,您可能理解并且(希望)接受这样一个事实:人类语言中的句子并不总是逐字翻译成另一种语言。以同样的方式,用各种SQL编写的SQL查询可能不会也不必转换为子句的不同品种子句。要翻译查询,您需要做两件事,同样重要的是:了解查询使和在目标SQL变种中具有多样性。
您正在翻译的存储过程实现了对特定表的动态排序行的动态分页。
关于分页,SQL Server没有本机语法,就像MySQL使用LIMIT ... OFFSET ...
功能一样。可能最典型的解决方法,您也可以在这里看到,使用ROW_NUMBER()
函数和子选择(在这种情况下,子选择恰好采用CTE的形式)。这是如何运作的? ROW_NUMBER()
根据特定的排序条件为子查询中的每一行分配数字,主查询只是过滤这些数字以获取行的范围,从而有效地为您提供页面。 / p>
你在MySQL中不需要任何类型的东西,因为它提供了LIMIT ...
和OFFSET ...
,当它们在存储过程的上下文中使用时,它们都可以接受整数类型的参数或本地整数类型变量作为它们的参数(好吧,它们可以if you are using MySQL 5.5.6+)。
至于动态排序,在SQL Server中,排序必须应用于ROW_NUMBER()
函数,因为它与动态分页一起使用。但是在MySQL中,您只需将ROW_NUMBER()
的{{1}}子句直接移动到(主)查询。
所以,最后,这是我提出的替代存储过程中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
的参数化只能以单引用(对参数或变量)的形式完成,即您不能使用表达式< / em>那里。所以,我不得不简单地使用上面的OFFSET
。但是,它将为您提供与SQL Server版本返回的页面不同的页面,除非您还更改OFFSET StartRow
语句,如下所示:
SET StartRow