Не удалось запустить оператор из-за проблемы с синтаксисом sql - PullRequest
0 голосов
/ 04 августа 2011

Это решение для неограниченного пейджинга 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

<</p>

Ошибки:

Преобразование не удалось при преобразовании значения varchar SELECT в тип данных int.

Пробовал также

 nvarchar and varchar. = + CAST(@first_id as varchar(10)) +

Ответы [ 4 ]

3 голосов
/ 04 августа 2011

Если вы пытаетесь реализовать пейджинг, это неправильно во многих отношениях. Во-первых, вы используете SET ROWCOUNT для ограничения @startRowIndex, но затем вы выбираете ВСЕ n строк (без ORDER BY), затем получаете первый идентификатор, а затем подсчитываете общее количество строк, выбирая из таблицы? Могу ли я предложить лучший подход?

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 голос
/ 04 августа 2011

Я предполагаю, что ваше поле @first_id является целым. Если это так, то вам нужно CAST / преобразовать значение @first_id в строку / varchar.

CAST(@first_id as varchar(10))

или

Convert(varchar(10), @first_id)

Документация MSDN по CAST / Convert для SQL-сервера

РЕДАКТИРОВАТЬ: После просмотра вашего запроса я замечаю, что вы устанавливаете свой @first_id = ID. Это неверный синтаксис, правильный синтаксис будет ниже.

SELECT @sql = 'SELECT ID AS ' + CAST(@first_id as varchar(10)) + ' FROM ' +
                    QUOTENAME(@currTable) + ' ORDER BY ID ' ; 

EXEC (@sql);
0 голосов
/ 04 августа 2011

Я бы сделал это так

create table #e (a int) 
SET @sql = 'insert #e SELECT COUNT(ID) FROM ' + @currTable + ' ';  
exec(@sql)
select @totalRows = a from #e
drop table #e 
0 голосов
/ 04 августа 2011

Похоже, вы пытаетесь создать псевдоним для своего столбца 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 ' ; 
...