Ошибка MS Access: оператор SELECT содержит зарезервированное слово или имя аргумента, которое написано с ошибкой или отсутствует, или пунктуация неверна - PullRequest
2 голосов
/ 16 июля 2009

[Обновление: запрос работает, если я жестко закодировал параметры, поэтому он связан с тем, как я добавляю параметры в запрос]

Что касается меня, я не могу понять, в чем здесь проблема.

Вот запрос, передаваемый в хранилище данных:

    SELECT * FROM (SELECT TOP ? StartDate, [ID] FROM
    (SELECT TOP ? StartDate, [ID] FROM Story 
    ORDER BY StartDate DESC, [ID] DESC) AS foo 
    ORDER BY StartDate ASC, [ID] ASC) AS bar 
    INNER JOIN Story AS t ON bar.ID = t.ID 
    ORDER BY bar.StartDate DESC, bar.[ID] DESC

Параметры добавляются в следующем порядке:

var pNumToRetrieve = new OleDbParameter("", OleDbType.Integer) {Value = numToGet};
var pResultSet = new OleDbParameter("", OleDbType.Integer) {Value = resultSet};

_cmd.Parameters.Add(pNumToRetrieve);
_cmd.Parameters.Add(pResultSet);

Если я ввожу этот запрос напрямую, он будет работать нормально. Однако при выполнении запроса из ASP.NET я получаю следующую ошибку:

Оператор SELECT содержит зарезервированное слово или имя аргумента, которое написано с ошибкой или отсутствует, или пунктуация неверна.

Что я делаю не так?

Спасибо

Адам

Ответы [ 6 ]

6 голосов
/ 16 июля 2009

N в TOP N запросов в Jet SQL не может быть параметризовано, точка. Вы должны написать строку SQL на лету, чтобы получить переменную N. Это означает, что вы не можете использовать сохраненный QueryDef или что вам нужно отредактировать SQL QueryDef и сохранить его перед его использованием.

2 голосов
/ 16 июля 2009

Рассмотрите возможность переписать ваши TOP N конструкции с использованием коррелированных подзапросов.

Вот простой пример. Рассмотрим таблицу с именем Sequence со столбцом (seq) уникальных INTEGER s (стандартная вспомогательная таблица SQL, которая полезна в бесчисленных ситуациях - в каждой базе данных должна быть одна!)

Оба следующих запроса возвращают два самых высоких значения для seq:

1)

SELECT TOP 2 seq 
  FROM SEQUENCE
 ORDER 
    BY seq DESC;

Плюсы: ядро ​​базы данных Access выполняет это относительно хорошо (как и следовало ожидать для собственного синтаксиса). Минусы: собственный синтаксис, поэтому плохо переносим. N (как в TOP N) не может быть параметризовано. Для меня использование DESC в ORDER BY для возврата наивысших значений нелогично.

2)

SELECT S1.seq 
  FROM SEQUENCE AS S1
 WHERE 2 >= (               
             SELECT COUNT(*)          
              FROM SEQUENCE AS S2       
             WHERE S2.seq >= S1.seq 
            );

Плюсы: поэтому стандартный синтаксис SQL хорош для переносимости. N может быть параметризован. Минусы: ядро ​​базы данных Access плохо оптимизирует коррелированные подзапросы, поэтому производительность будет снижаться по мере увеличения числа строк в таблице (как и всегда при проблемах с производительностью, вам нужно будет это проверить). Некоторые SQL-кодеры находят коррелированный подзапрос сложным для понимания и, следовательно, имеют потенциальные проблемы с обслуживанием.

0 голосов
/ 16 июля 2009

Посмотрите, поможет ли изменение запроса таким способом.

PARAMETERS numToGet number, rowsToGet numeric;
SELECT * FROM (SELECT TOP numToGet StartDate, [ID] FROM
    (SELECT TOP rowsToGet StartDate, [ID] FROM Story 
    ORDER BY StartDate DESC, [ID] DESC) AS foo 
    ORDER BY StartDate ASC, [ID] ASC) AS bar 
    INNER JOIN Story AS t ON bar.ID = t.ID 
    ORDER BY bar.StartDate DESC, bar.[ID] DESC

РЕДАКТИРОВАТЬ: На заметку, какое значение передается с использованием этих двух параметров? Оба числа?

0 голосов
/ 16 июля 2009

Нравится ли порядок в подзапросах? Это не поддерживается в SqlServer.

Редактировать: Моя ошибка, я пропустил Топ?

0 голосов
/ 16 июля 2009

Является ли параметр pResultSet типизированным как OleDbTypeInteger?

0 голосов
/ 16 июля 2009

Я заметил, что не все столбцы идентификаторов имеют квадратные скобки вокруг них. Это может быть так, но я давно играл с Access, так что у кого-то еще может быть лучший ответ.

EDIT:

Пока тебе не повезло, я попытаюсь сделать еще одно предположение. Не могли бы вы попробовать изменить "*", чтобы вместо этого явно указать нужные столбцы.

Окончательное редактирование:

Последний совет, который я могу предложить, - заменить запрос очень простой версией, которая не дает результатов. Затем дайте ему тест, если он терпит неудачу, это должен быть код параметра, который терпит неудачу, если нет, то это что-то в сложности запроса. Если вы постепенно восстанавливаете запрос, вы сможете определить точку сбоя. Извините, я не могу больше помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...