2013-08-06 2 views
0

У меня есть оператор SQL Update, который при запуске в VS2010 через новое окно запроса работает, но когда я его структурирую как инструкцию обновления, ничего не происходит.Оператор обновления SQL ничего не делает

Мне было интересно, может ли кто-нибудь увидеть, что я делаю неправильно? Как я уже сказал, код работает, когда выполняется через окно запроса в VS2010.

Вот мой код:

SqlConnection connection = new SqlConnection(DBConnection.GetConnection().ConnectionString); 

string updateStatement = 
    "DECLARE @OldParent hierarchyid, @NewParent hierarchyid " + 

    "SELECT @OldParent = Hierarchy FROM SpecProducts " + 
    "WHERE ID = @NodeToMoveID ; ------ top item to be moved " + 

    "SELECT @NewParent = Hierarchy FROM SpecProducts " + 
    "WHERE ID = @NodeToMoveIntoID ; -- ID of item to move into - new parent " + 

    "DECLARE children_cursor CURSOR FOR " + 
    "SELECT Hierarchy FROM SpecProducts " + 
    "WHERE Hierarchy = @OldParent; " + 

    "DECLARE @ChildId hierarchyid; " + 
    "OPEN children_cursor " + 

    "FETCH NEXT FROM children_cursor INTO @ChildId; " + 

    "WHILE @@FETCH_STATUS = 0 " + 
    "BEGIN " + 
    "START: " + 

     "DECLARE @NewId hierarchyid; " + 
     "SELECT @NewId = @NewParent.GetDescendant(MAX(Hierarchy), NULL) " + 
     "FROM SpecProducts WHERE Hierarchy.GetAncestor(1) = @NewParent; " + 

     "UPDATE SpecProducts " + 
     "SET Hierarchy = Hierarchy.GetReparentedValue(@ChildId, @NewId), " + 
      "MovedToDate = @MovedToDate, " + 
      "MovedToBy = @MovedToBy " + 
     "WHERE Hierarchy.IsDescendantOf(@ChildId) = 1; " + 

     "IF @@error <> 0 GOTO START -- On error, retry " + 
     "FETCH NEXT FROM children_cursor INTO @ChildId; " + 
     "END " + 

     "CLOSE children_cursor; " + 
     "DEALLOCATE children_cursor;"; 

SqlCommand updateCommand = new SqlCommand(updateStatement, connection); 
updateCommand.Parameters.AddWithValue("@NodeToMoveID", nodeIDToMove); 
updateCommand.Parameters.AddWithValue("@NodeToMoveIntoID", newParentID); 
updateCommand.Parameters.AddWithValue("@MovedToDate", DateTime.Now); 
updateCommand.Parameters.AddWithValue("@MovedToBy", userModifying.ID); 

try 
{ 
    connection.Open(); 
    updateCommand.ExecuteNonQuery(); 

    return true; 
} 

Одна вещь, чтобы указать на то, что, когда мой код выполняется в окне VS2010 запросов, я получаю предупреждение о «Declare» особенность, но я нажимаю продолжить, и она работает. Не работает ли мое заявление недействительное с функциями Declare?

Любые мысли/решения были бы весьма признательны.

Большое спасибо.

Роб

+1

Боковое примечание: вы должны ** закрыть ** ваше соединение сразу после выполнения запроса ... –

+1

Вместо жесткого кодирования этих операторов sql, почему бы вам не превратить его в хранимую процедуру? – unlimit

+0

Если вы поставили точку останова в 'SqlCommand updateCommand = new SqlCommand (updateStatement, connection);' и получить значение 'updateStatement', запустите это в окне запроса, это работает? – christiandev

ответ

1

Я добавляю это как ответ, так как комментарий дискуссия становится немного долго.

В соответствии с documentation, ExecuteNonQuery возвращает -1, когда происходит откат базы данных. Это, вероятно, связано с ошибкой, вы дали:

источник ошибки: .net.sqlclient поставщика данных
Сообщение об ошибке: должен объявить скалярную variabe NodeToMoveID & NodeToMoveIntoID & MovedToDate.

Как вы упомянули, у вас возникли проблемы с использованием параметров SQL. Одним из решений этого является замена этих параметров переменными в updateStatement.

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

Смежные вопросы