【问题标题】:Not able to run a statement because of issue with the sql syntax由于 sql 语法问题,无法运行语句
【发布时间】:2011-08-03 20:29:49
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    如果您尝试实现分页,这在很多方面都是错误的。首先,您使用 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个cmets关注:

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

    【讨论】:

      【解决方案2】:

      我猜你的@first_id 字段是一个整数。如果是这样,那么您需要将您的 @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);
      

      【讨论】:

      【解决方案3】:

      您似乎正在尝试为您的列 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 ' ; 
      

      【讨论】:

        【解决方案4】:

        我会这样做

        create table #e (a int) 
        SET @sql = 'insert #e SELECT COUNT(ID) FROM ' + @currTable + ' ';  
        exec(@sql)
        select @totalRows = a from #e
        drop table #e 
        

        【讨论】:

          猜你喜欢
          • 2017-09-06
          • 2021-06-23
          • 2020-06-27
          • 1970-01-01
          • 2011-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多