xhon Ответов: 1

Манипулируйте объектом в БД, вызывая хранимую процедуру


Я создал хранимую процедуру для удаления объекта из таблицы Кино в моей БД и я вызвал его из а DataAccessLayer метод моего приложения (C#).

Я передал хранимую процедуру в качестве параметра Команда sqlcommand объект вместе с Объект sqlconnection объект, затем я добавил параметры хранимой процедуры с помощью метода Параметры , который называется Команда sqlcommand объект.
Метод не работает (элемент не был удален); поскольку он не вызвал никакого исключения, я полагаю, что проблема вызвана несоответствием между параметрами в хранимой процедуре и теми, которые я пытаюсь добавить сюда...
Хранимая процедура работает нормально.

Что я уже пробовал:

public bool Delete(Movie movie)  
        {
            try
            {
                bool result = false;
                string DeleteProcedure = "[dbo].nameOfTheProcedure";
                using (SqlConnection conn = DB.GetSqlConnection())
                {
                    using (SqlCommand cmd = new SqlCommand(DeleteProcedure, conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.Add("@MovieId", SqlDbType.NVarChar).Value = movie.Id;
                        cmd.Parameters.Add("@Title", SqlDbType.NVarChar).Value = movie.Title;
                        
                        cmd.Parameters.Add("@Director", SqlDbType.NVarChar).Value = movie.Director;                       
                        conn.Open();
                        result = cmd.ExecuteNonQuery() == 1;
                    }
                }
                return result;
            }
            catch (SqlException ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

PIEBALDconsult

Никогда не удалять.

1 Ответов

Рейтинг:
7

OriginalGriff

Это будет зависеть от того, как на самом деле выглядит SP: это должно быть что-то вроде этого:

CREATE PROCEDURE [dbo].[nameOfTheProcedure]
@MOVIEID NVARCHAR(10),
@TITLE NVARCHAR(MAX)  -- This should be irrelevent - the ID should be unique.
AS
   DELETE FROM [dbo].[YourDBTableName]
   WHERE Id = @MOVIEID
GO


xhon

моя хранимая процедура работает, просто метод C# возвращает false вместо true, потому что элемент не был удален (хотя я могу удалить его, вызвав свою хранимую процедуру в приложении db manager)

OriginalGriff

Откуда вы знаете, что это работает? Как вы это проверили?
Чем отличается то, как вы его тестировали, по сравнению с тем, как вы его сейчас называете?

xhon

хранимая процедура работает, когда я вызываю ее из диспетчера Sql Server, в то время как метод в Visual Studio, где я вызываю хранимую процедуру, не возвращает ожидаемого результата

OriginalGriff

Но когда вы вызываете его из SSMS, вы передаете параметры вручную и, возможно, по-другому.
Поэтому используйте отладчик и посмотрите на две вещи: что именно содержится в передаваемых вами параметрах и что именно возвращает вызов ExecuteNonQuery?
Чем это отличается от способа SSMS?

xhon

нет, я не передаю параметры вручную, я передаю их непосредственно из метода C#. Я проверил их, сохранив результаты "cmd.Parameters.Добавьте" операторы для переменных (по одному для каждого добавленного параметра), и они будут правильными. Я назначил результат "cmd.ExecuteNonQuery == 1" к переменной "result", и метод возвращает ее, и она ложна (поэтому результат ExecuteNonQuery==1 является ложным), а не истинным

OriginalGriff

Итак, когда вы тестировали его с помощью SSMS, как вы передавали параметры, если не вручную? Когда вы щелкаете правой кнопкой мыши SP и выбираете "выполнить", появляется диалоговое окно для ввода значений параметров. Что - именно - вы туда вошли?

И что - именно - вернул ExecuteNonQuery? Не "что он вернул, что, вероятно, не было 1?", а фактическое значение. Первое правило отладки: "собирай информацию, а не догадки". :смеяться:

xhon

ExecuteNonQuery возвращает значение -1.
Обновление: я вставил новые элементы в БД из C#, и мне удалось удалить их с помощью этого метода (ExecuteNonQuery stills возвращает -1, а ExecuteNonQuery() == 1 все еще возвращает false), но операция удаления завершилась неудачей, когда я попытался удалить элементы, уже находящиеся в БД (т. е. те строки, которые были созданы в среде Sql Management Studio, а не добавлены из моего приложения)... Я предполагаю, что проблема может быть в несоответствии между свойствами столбцов в БД и атрибутами соответствующих сущностей, но в этот момент я задаюсь вопросом, почему ExecuteNonQuery возвращает -1 (разве это не должно быть 1?), даже если операция удаления успешна.

OriginalGriff

Поэтому вам нужно посмотреть на SP и посмотреть, что именно он делает.
Я не могу сделать это для тебя!

OriginalGriff

О, и еще одна глупая мысль.
Вы проверили, что SSMS и Ваше приложение C# определенно используют одну и ту же БД, не так ли?

xhon

Я решил эту проблему!:) некоторые элементы не удалось удалить из-за ссылочной целостности, я отредактировал свою БД, и теперь все работает нормально (но я до сих пор не понимаю, почему ExecuteNonQuery возвращает -1)

OriginalGriff

Как я уже сказал: Посмотрите на ваш SP - мы не можем видеть его или как он работает!

xhon

Я ее разгадал! Это зависело от того, что я установил NOCOUNT в своем SP. Теперь я прокомментировал это утверждение, и ExecuteNonQuery возвращает ожидаемое число. Спасибо за советы

OriginalGriff

Всегда пожалуйста!