Не удается выполнить правильную команду SQL-запроса с SQL Compact - PullRequest
0 голосов
/ 23 сентября 2011

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

Функция удаления / деаутентификации / аннулирования существующего сеанса сначала проверяет, существует ли пользователь с помощью другого метода, реализованного следующим образом:

        int userId = 0;
        SqlCeCommand cmd = new SqlCeCommand();
        SqlCeParameterCollection sqlParams = cmd.Parameters;
        sqlParams.AddWithValue("@User", userName);
        cmd.Connection = this.conn;
        cmd.CommandText = "SELECT Id FROM Users WHERE (Username = @User)";

        userId = (int) cmd.ExecuteScalar()
        cmd.Dispose();

После этого он пытается найти существующий сеанс для этого пользователя, который должен быть удален (снова другим способом):

        SqlCeCommand cmd = new SqlCeCommand();
        SqlCeParameterCollection sqlParams = cmd.Parameters;
        sqlParams.AddWithValue("@SID", mysession);
        sqlParams.AddWithValue("@UID", myuserid);

        cmd.Connection = this.Connection;
        cmd.CommandText = "SELECT Id FROM UserSessions WHERE (SessionID = @SID) AND (User_Id = @UID)";
        int foo = cmd.ExecuteNonQuery();

... что не получается. К сожалению, не исключение. Поэтому я добавил небезопасный эквивалент, используя непараметризованную строку запроса:

        cmd.CommandText = String.Format("SELECT Id FROM UserSessions WHERE (SessionID = '{0}') AND (User_Id = {1})", mysession, myuserid);
        cmd.Prepare();
        int bar = cmd.ExecuteNonQuery();

Добавил точку останова, приостановил, скопировал, вставил запрос в инструмент Visual Studio Query и вуаля, он действительно работал . Но после продолжения этот запрос в коде также не прошел . Я не могу найти виновника этой надоедливой проблемы, поскольку исключение не выдвигается и все кажется правильным. Данные существуют, параметры представлены в правильных типах (string и int), и мне не о чем проверять. Соединение открытое и пр.

Какие-нибудь подсказки от кого-либо вокруг? Спасибо!

Обновление : Mea culpa, упустил тот факт, что функция использовала ExecuteScalar, пока я не изменил ее для тестирования. использует , использует ExecuteScalar, а возвращает нулевое значение , на всякий случай.

Ответы [ 2 ]

2 голосов
/ 23 сентября 2011

Вы используете ExecuteNonQuery:

int foo = cmd.ExecuteNonQuery();

... но вы явно пытаетесь выполнить запрос (ВЫБРАТЬ)!Снова используйте ExecuteScalar, как вы делали в первом коде, или ExecuteReader и просмотрите результаты соответствующим образом.Если вы придерживаетесь ExecuteScalar, вы должны сначала проверить, равен ли результат null, чтобы указать отсутствие результатов.

ExecuteNonQuery возвращает количество строк, затронутых UPDATE / INSERTКоманда / DELETE - для чего она и предназначена.Я подозреваю, что он возвращает -1 для вас, как задокументировано:

Для операторов UPDATE, INSERT и DELETE возвращаемое значение - это количество строк, затронутых командой.Если для вставляемой или обновляемой таблицы существует триггер, возвращаемое значение включает количество строк, на которые влияет операция вставки или обновления, а также количество строк, на которые влияет триггер или триггеры. Для всех других типов операторов возвращаемое значение равно -1. Если происходит откат, возвращаемое значение также равно -1.

(Выделение мое.)

1 голос
/ 23 сентября 2011

Используйте set [], чтобы избежать неоднозначности с ключевым словом базы данных.

  cmd.CommandText = "SELECT [Id] FROM [Users] WHERE ([Username] = @User)";

и используйте метод ExecuteScalar() или ExecureReader() при работе с операторами SELECT.

...