Оператор C# SQL — синтаксическая ошибка в запросе. Неполное предложение запроса

Ниже приведен код, который у меня есть, я не могу понять, что не так с запросом.

Первоначально у меня была ошибка «нет значения для 1 или более параметров», которая, похоже, исчезла (хотя, опять же, я даже не знаю, почему я ее получаю).

Соединение открывается до этого кода. Параметр GVars.thisFY представляет собой строку = "FY13" - эта таблица точно существует. Параметр GVars.currentDate представляет собой DateTime = сегодня.

Записи определенно существуют для этого диапазона [Destination] и [Next Collection]:

string sql;
OleDbDataAdapter adapter;

sql = "SELECT * FROM @CurFY WHERE [Destination] = @Destination AND [Next Collection] BETWEEN @NextCollectionA AND @NextCollectionB;";

// Create the command object
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;

// Add values to the fields
cmd.Parameters.AddWithValue("@CurFY", GVars.thisFY);
cmd.Parameters.AddWithValue("@Destination", "Henwood");
cmd.Parameters.AddWithValue("@NextCollectionA", GVars.currentDate);
cmd.Parameters.AddWithValue("@NextCollectionB", GVars.currentDate.AddDays(1));

adapter = new OleDbDataAdapter(cmd.CommandText, conn);

try
{
    adapter.Fill(ds);

    GVars.bLblLastUpdate = DateTime.Now.ToString("HH:mm:ss");
}
catch (Exception ex)
{
}

РЕДАКТИРОВАТЬ: я изменил код, чтобы удалить параметр таблицы, как показано ниже, по-прежнему получая «значение не указано для 1 или более параметров», хотя я не могу определить.

EDIT2: я удалил лишние материалы, поэтому сообщение относится только к исходному вопросу, на который был дан ответ. Я задам новый вопрос для моей странной ошибки «нет значения».


person iabbott    schedule 10.06.2013    source источник
comment
Вы не можете использовать имя таблицы в качестве параметра. См. также этот вопрос: stackoverflow.com/questions/14124261/   -  person René Wolferink    schedule 10.06.2013
comment
ваша главная ошибка здесь заключалась в том, что вы проглотили исключение; очень мало хороших мест для этого, и это не одно из них   -  person Marc Gravell    schedule 10.06.2013
comment
Какую систему баз данных (и какую версию) вы используете? SQL — это просто язык запросов, и он используется во многих системах баз данных, что на самом деле ничего нам не говорит…   -  person marc_s    schedule 10.06.2013
comment
база данных находится в Access (формат 2003-2003)   -  person iabbott    schedule 10.06.2013
comment
@ Марк Гравелл, что ты имеешь в виду? Блок catch пуст, так как я использую его только для того, чтобы увидеть ошибку, которую производит мое кодирование, после того, как она будет отсортирована, я добавлю менее общий catch для проблем с сетью/базой данных и т. д. Это то, что вы имели в виду?   -  person iabbott    schedule 10.06.2013


Ответы (2)


Вы не можете параметризовать запросы с именами таблиц, представлений или столбцов. Только элементы данных могут быть параметризованы.

Вам нужно сделать свой SQL динамическим, например. как это:

sql = string.Format(
    "SELECT * FROM {0} WHERE [Destination] = @Destination AND [Next Collection] BETWEEN @NextCollectionA AND @NextCollectionB;"
,  GVars.thisFY
);

Это следует делать только в том случае, если GVars.thisFY контролируется вашим кодом, например. происходит из предварительно определенного списка или проверяется на отсутствие символов, отличных от буквенно-цифровых, во избежание атак с внедрением SQL.

person Sergey Kalinichenko    schedule 10.06.2013
comment
разве я не чувствую себя глупо... хорошо, удалил этот параметр, теперь он снова говорит мне, что для 1 или более параметров не задано значение - person iabbott; 10.06.2013
comment
Если GVars.thisFY каким-то образом поступает от клиента (например, раскрывающийся список, который можно изменить вручную), это создает уязвимость в системе безопасности. Дезинфицируйте свой ввод, прежде чем вставлять его в запрос. - person René Wolferink; 10.06.2013
comment
@IanAbbott не указано значение для 1 или более параметров. Странно ... Вы также удалили @ из запроса? В вашем запросе сейчас должно быть только 3 @, а в коде должно быть 3 вызова AddWithValue. - person Sergey Kalinichenko; 10.06.2013
comment
я обновил свой исходный пост текущим исправленным кодом - person iabbott; 10.06.2013
comment
@IanAbbott Ваша отредактированная версия должна была сработать (не уверен насчет точки с запятой в конце, но я не работал с MS Access через C#, поэтому не могу сказать наверняка). - person Sergey Kalinichenko; 10.06.2013
comment
нет, не работает... Я пробовал с точкой с запятой в конце и без нее (хотя я обычно не ставлю точку с запятой в конце и не имею проблем) - person iabbott; 10.06.2013
comment
@IanAbbott Просто предложение: код был бы более надежным (и, возможно, несколько более безопасным), если бы имя таблицы было заключено в квадратные скобки, то есть SELECT * FROM [{0}] .... - person Gord Thompson; 10.06.2013

Попробуй это -

sql = Sring.Format(
    "SELECT * FROM {0} WHERE [Destination] = @Destination AND [Next Collection] BETWEEN @NextCollectionA AND @NextCollectionB;", 
    GVars.thisFY
)

cmd.Parameters.AddWithValue("@Destination", "Henwood");
cmd.Parameters.AddWithValue("@NextCollectionA", GVars.currentDate);
cmd.Parameters.AddWithValue("@NextCollectionB", GVars.currentDate.AddDays(1));
person Devart    schedule 10.06.2013
comment
Если GVars.thisFY каким-то образом поступает от клиента (например, раскрывающийся список, который можно изменить вручную), это создает уязвимость в системе безопасности. Дезинфицируйте свой ввод, прежде чем вставлять его в запрос. - person René Wolferink; 10.06.2013