此解决方案适用于无限制的Gridview
分页,并且此查询的语法存在问题:
> @currTable varchar(20),
@startRowIndex int,
@maximumRows int,
@totalRows int OUTPUT
AS
DECLARE @first_id int, @startRow int
IF @startRowIndex = 1
SET @startRowIndex = 1
ELSE
SET @startRowIndex = ((@startRowIndex - 1) * @maximumRows)+1
SET ROWCOUNT @startRowIndex
DECLARE @sql varchar(250);
SET @sql = 'SELECT ID, StringID_from_Master, GUID, short_Text, lang_String, date_Changed, prev_LangString, needsTranslation, displayRecord, brief_Descrip FROM ' + @currTable + ' ';
EXECUTE(@sql);
PRINT @first_id
SET ROWCOUNT @maximumRows
SELECT @sql = 'SELECT ' + CAST(@first_id as varchar(20)) + ' = ID FROM ' + QUOTENAME(@currTable) + ' ORDER BY ID ' ;
EXEC (@sql);
SET ROWCOUNT 0
-- Get the total rows
SET @sql = 'SELECT ' + + CAST(@totalRowsas varchar(20)) + ' = COUNT(ID) FROM ' + @currTable + ' ';
EXECUTE(@sql);
RETURN
<
错误是:
将varchar值''SELECT'转换为数据类型int时转换失败。
也试过
nvarchar and varchar. = + CAST(@first_id as varchar(10)) +
答案 0 :(得分:3)
如果您正在尝试实现分页,这在很多方面都是错误的。首先,您使用SET ROWCOUNT限制为@startRowIndex,但是您选择了所有n行(没有ORDER BY),然后获取第一个ID,然后通过从表中选择来计算总行数?我可以建议一个更好的方法吗?
CREATE PROCEDURE dbo.PageSmarter
@Table NVARCHAR(128), -- table names should not be varchar(20)
@FirstRow INT,
@PageSize INT,
@TotalRows INT OUTPUT
AS
BEGIN
SET NOCOUNT ON; -- always, in every stored procedure
DECLARE
@first_id INT,
@startRow INT,
@sql NVARCHAR(MAX);
SET @sql = N'WITH x AS
(
SELECT
ID,
rn = ROW_NUMBER() OVER (ORDER BY ID)
FROM
' + @Table + '
)
SELECT rn, ID
INTO #x FROM x
WHERE rn BETWEEN ' + CONVERT(VARCHAR(12), @FirstRow)
+ 'AND (' + CONVERT(VARCHAR(12), @FirstRow)
+ ' + ' + CONVERT(VARCHAR(12), @PageSize) + ' - 1);
SELECT first_id = MIN(ID) FROM #x;
SELECT
ID, StringID_from_Master, GUID, short_Text, lang_String, date_Changed,
prev_LangString, needsTranslation, displayRecord, brief_Descrip
FROM ' + @Table + ' AS src
WHERE EXISTS
(
SELECT 1 FROM #x
WHERE ID = src.ID
);';
EXEC sp_executeSQL @sql;
SELECT @totalRows = SUM(row_count)
FROM sys.dm_db_partition_stats
WHERE [object_id] = OBJECT_ID(@Table);
END
GO
DECLARE @tr INT;
EXEC dbo.PageSmarter 'dbo.tablename', 10, 2, @tr OUTPUT;
SELECT @tr;
我没有使用此特定实现测试所有边缘情况。我承认,有更好的方法可以做到这一点,但它们通常并没有复杂的动态表名的额外要求。这表明如果您可以针对任意数量的表运行完全相同的查询并获得类似的结果,那么您的设计本身就存在一些错误。
在任何情况下,您都可以查看有关在SQL Server Central上进行分页的各种方法的一些(非常冗长的)讨论:
http://www.sqlservercentral.com/articles/T-SQL/66030/
该文章有62条评论:
http://www.sqlservercentral.com/Forums/Topic672980-329-1.aspx
答案 1 :(得分:1)
我猜你的@first_id字段是一个int。如果是这样,那么您需要将@first_id值CAST /转换为字符串/ varchar。
CAST(@first_id as varchar(10))
或
Convert(varchar(10), @first_id)
MSDN documentation on CAST/Convert for SQL server
编辑:再次查看您的查询后,我注意到您正在设置@first_id = ID,这是不正确的语法,正确的语法将在下面。
SELECT @sql = 'SELECT ID AS ' + CAST(@first_id as varchar(10)) + ' FROM ' +
QUOTENAME(@currTable) + ' ORDER BY ID ' ;
EXEC (@sql);
答案 2 :(得分:0)
您似乎正在尝试为列ID
创建别名。您正在构建的字符串不会生成有效的SQL语句如果它包含数字。它会出现这样的事情:
SELECT 123 = ID FROM dbo.MyTable ORDER BY ID
试试这个:
SELECT ID AS '123' FROM dbo.MyTable ORDER BY ID
实现这一目标:
SELECT @sql = 'SELECT ID AS ''' + CAST(@first_id as varchar(10)) +
''' FROM ' + QUOTENAME(@currTable) +
' ORDER BY ID ' ;
答案 3 :(得分:0)
我会这样做
create table #e (a int)
SET @sql = 'insert #e SELECT COUNT(ID) FROM ' + @currTable + ' ';
exec(@sql)
select @totalRows = a from #e
drop table #e