由于sql语法问题,无法运行语句

时间:2011-08-03 20:29:49

标签: sql-server tsql sql-server-2008 sql-server-express

此解决方案适用于无限制的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)) +

4 个答案:

答案 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