2011-08-03 30 views
0

该解决方案是一个无限Gridview寻呼和有问题,此查询的语法:无法运行,因为与SQL语法问题的声明

> @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)) + 

回答

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的中央传呼过来:

http://www.sqlservercentral.com/articles/T-SQL/66030/

上有文章跟进62篇评论:

http://www.sqlservercentral.com/Forums/Topic672980-329-1.aspx

1

我猜你@first_id场是一个int。如果是这样,那么您需要CAST /将您的@first_id值转换为字符串/ 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); 
+0

请不要指定没有长度的'VARCHAR'。有关更多信息,请参阅以下博客文章:http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length.aspx –

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 ' ; 
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