Что я делаю не так с этим запросом? - PullRequest
0 голосов
/ 15 июля 2009

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

РЕДАКТИРОВАТЬ: вот так выглядит мой запрос .. все еще ничего ..

connection.Open();
XmlNodeList nodeItem = rssDoc.SelectNodes("/edno23/posts/post");

foreach (XmlNode xn in nodeItem)
{
    cmd.Parameters.Clear();
    msgText = xn["message"].InnerText;
    C = xn["user_from"].InnerText;
    avatar = xn["user_from_avatar"].InnerText;
    string   endhash =  GetMd5Sum(msgText.ToString());
    cmd.Parameters.Add("@endhash",endhash);
    cmd.CommandText  = "Select * FROM posts Where hash=@endhash";
    SqlCeDataReader reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        string msgs = reader["hash"].ToString();

        if (msgs != endhash || msgs == null)
        {
            sql = "INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(@username,@messige,@userpic,@thedate,@hash)";
            cmd.CommandText = sql;
            cmd.Parameters.Add("@username", C);
            cmd.Parameters.Add("@messige", msgText.ToString());
            cmd.Parameters.Add("@userpic", avatar.ToString());
            cmd.Parameters.Add("@thedate", dt);
            cmd.Parameters.Add("@hash", endhash);
            cmd.ExecuteNonQuery();// executes query
            adapter.Update(data);// saves the changes
        }
    }

    reader.Close();
}

connection.Close();

Ответы [ 7 ]

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

Есть ли в nodeItem какие-либо элементы? Если нет, содержимое цикла foreach не выполняется.

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

Что на самом деле содержит хэш? Если это хеш, почему вы хэшируете содержимое хеша внутри цикла while? Если нет, то почему он сравнивается с хешем в запросе SELECT * FROM posts WHERE hash = @endhash?

Не закроет ли соединение до конца цикла while, сделает недействительным считыватель, используемый для управления циклом?

1 голос
/ 17 июля 2009

У вас есть некоторые проблемы с невыполнением блоков "использования". Я добавил немного к вашему внутреннему коду ниже. Блоки для соединения и выбора команды более желательны с моей стороны. Я надеюсь, что вы делаете то же самое с адаптером данных.

using (var connection = new SqlCeConnection(connectionString))
{
    connection.Open();
    var nodeItem = rssDoc.SelectNodes("/edno23/posts/post");

    foreach (XmlNode xn in nodeItem)
    {
        using (
            var selectCommand =
                new SqlCeCommand(
                    "Select * FROM posts Where hash=@endhash",
                    connection))
        {
            var msgText = xn["message"].InnerText;
            var c = xn["user_from"].InnerText;
            var avatar = xn["user_from_avatar"].InnerText;
            var endhash = GetMd5Sum(msgText);
            selectCommand.Parameters.Add("@endhash", endhash);
            selectCommand.CommandText =
                "Select * FROM posts Where hash=@endhash";
            using (var reader = selectCommand.ExecuteReader())
            {
                while (reader.Read())
                {
                    var msgs = reader["hash"].ToString();

                    if (msgs == endhash && msgs != null)
                    {
                        continue;
                    }

                    const string COMMAND_TEXT =
                        "INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(@username,@messige,@userpic,@thedate,@hash)";
                    using (
                        var insertCommand =
                            new SqlCeCommand(
                                COMMAND_TEXT, connection))
                    {
                        insertCommand.Parameters.Add("@username", c);
                        insertCommand.Parameters.Add(
                            "@messige", msgText);
                        insertCommand.Parameters.Add(
                            "@userpic", avatar);
                        insertCommand.Parameters.Add("@thedate", dt);
                        insertCommand.Parameters.Add(
                            "@hash", endhash);
                        insertCommand.ExecuteNonQuery();
                            // executes query
                    }
                    adapter.Update(data); // saves teh changes
                }

                reader.Close();
            }
        }
    }

    connection.Close();
}

Конечно, при дополнительном вложении детали следует разбивать на отдельные методы.

1 голос
/ 15 июля 2009

Возвращено ли что-нибудь из сообщения "Выбрать * ИЗ сообщений, где хэш = @ endhash"?

Если нет, то ничего внутри цикла while не имеет значения ....

1 голос
/ 15 июля 2009

Почему вы закрываете соединение с базой данных внутри цикла while?
Код, который вы опубликовали , должен вызывать исключение при попытке вызвать cmd.ExecuteNonQuery () с неоткрытым объектом подключения к БД.

SqlCeCommand.ExecuteNonQuery () метод возвращает количество затронутых строк.
Почему бы вам не проверить, возвращает ли он 1 или нет в отладчике, как показано ниже?

int rowsAffectedCount = cmd.ExecuteNonQuery();

Надеюсь, это поможет: -)

1 голос
/ 15 июля 2009

Здесь происходит много всего ...

Вы используете команду 'cmd' для зацикливания записей с помощью устройства чтения данных, а затем используете ту же команду 'cmd' внутри оператора while для выполнения оператора вставки. Вы ранее объявили другую команду «cmdAdd», но, кажется, нигде ее не используете; это то, что вы намеревались использовать для оператора вставки?

Вы также закрываете свое соединение для передачи данных внутри цикла while, который выполняет итерации по вашему устройству чтения данных. Вы только прочитаете одну запись и затем закроете соединение с вашей базой данных таким образом; если ваше условие для вставки не выполнено, вы ничего не напишите в базу данных.

EDIT:

Вы действительно должны открыть и закрыть соединение с базой данных вне foreach на узлах xmlnodes. Если у вас есть 10 узлов для зацикливания, соединение БД будет открываться и закрываться 10 раз (ну, пул соединений, вероятно, предотвратит это, но все же ...)

Вы также загружаете всю таблицу 'posts' в набор данных, по-видимому, без причины. Вы не изменяете ни одно из значений в наборе данных, но неоднократно вызываете обновление для него (в «save the shanges»). Если таблица «posts» даже удаленно велика, это будет бесполезно высасывать много памяти (на портативном устройстве, не меньше).

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

Я подозреваю, что ваша проблема в том, что вы пытаетесь использовать одни и те же экземпляры SqlCeCommand.

Попробуйте создать новый SqlCeCommand в цикле while. Кроме того, вы можете использовать оператор using, чтобы закрыть ваши объекты данных.


Почему вы звоните adapter.Update(data), поскольку вы вообще не меняете DataSet? Я подозреваю, что вы хотите позвонить adapter.Fill(data). Метод Update сохранит все изменения в наборе данных в базе данных.

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

Как отлаживать программы: http://www.drpaulcarter.com/cs/debug.php

Серьезно, вы можете опубликовать дополнительную информацию о том, где это работает? Работает ли это, если вы используете SQL Server Express вместо SQL CE? Если да, можете ли вы запустить SQL Profiler и взглянуть на выполняемые команды SQL?

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