Проблема с хранимой процедурой вставки формата даты - PullRequest
1 голос
/ 08 октября 2019

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

неправильный синтаксис рядом с '-'.

Iтакже попытался с апострофом, но затем я получаю сообщение об ошибке при преобразовании типа данных числовой в intЯ проверил, имеет ли моя таблица правильный формат, и это делает. Любая идея, что происходит?

ALTER PROC [dbo].[UbaciVlasnika]
    (@ImeVlasnika NVARCHAR(50),
     @PrezimeVlasnika NVARCHAR(50),
     @DatumRodjenja DATE,
     @JMBG INT,
     @VlasnikID INT OUTPUT)
AS
    INSERT INTO Vlasnik 
    VALUES (@ImeVlasnika, @PrezimeVlasnika, @DatumRodjenja, @JMBG)

    SELECT @VlasnikID = SCOPE_IDENTITY()

PS: Я также пытался вставить значения с помощью

INSERT INTO Vlasnik 
VALUES ('xxxxx', 'xxxx', 'YYYY-MM-DD', 'xxxxx')

, и это работает.

Ответы [ 3 ]

0 голосов
/ 08 октября 2019

Проблема на самом деле в вашем графическом интерфейсе. Код должен выглядеть примерно так (например, C #):

    var cmd = new SqlCommand("UbaciVlasnika", "connstr");
    cmd.CommandType=CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@ImeVlasnika", "some text");
    cmd.Parameters.AddWithValue("@PrezimeVlasnika", "some text");

    //ATTENTION! parse the string to date type; don't pass a string into to a date type parameter
    cmd.Parameters.AddWithValue("@DatumRodjenja", DateTime.ParseExact("2019-01-01", "yyyy-MM-dd", CultureInfo.InvariantCulture));

    //OR IF YOU ALREADY HAVE A DATE
    cmd.Parameters.AddWithValue("@DatumRodjenja", myDateTimePicker.Value);

    cmd.Parameters.AddWithValue("@JMBG", 12345);
    cmd.Parameters.Add("@VlasnikID", SqlDbType.Int).Direction = ParameterDirection.Output;
    con.Open();
    int returnCode = cmd.ExecuteNonQuery();
    con.Close();

    MessageBox.Show("Output was " + (int)cmd.Parameters["@VlasnikID"].Value);

В клиентском приложении мы явно анализируем параметры, чтобы убедиться, что мы передаем правильный тип данных на сервер, а нечем полагаться на неявное преобразование. Сервер БД может находиться в другом регионе, чем приложение, которое вызывает эту процедуру, и, следовательно, иметь другое представление о том, как форматируются даты. Клиентское приложение должно всегда выполнять ословую работу по синтаксическому анализу аргумента, если только вы не измените сигнатуру своей процедуры, чтобы она принимала varchar и специально конвертировала дату внутри процедуры - я бы избегал делать это по вышеупомянутым причинам о том, что интерфейс знает/ забота о регионах, локализации и культуре и т. д., в то время как внутренняя база данных может / должна оставаться в неведении об этих вещах

Если вы используете SSMS для быстрого тестирования этого SP, сделайте следующее:

DECLARE @return_value int;
DECLARE @VlasnikID int; 
DECLARE @im NVARCAHR(50) = N'Petar';
DECLARE @pv NVARCAHR(50) = N'Petrović';
DECLARE @dr DATE = '1897-03-20'; --or CONVERT(date, '1897-03-20', 20)
DECLARE @jm INT = 2003897710341; --this is way larger than int's max value 2147483647 - change it!

EXEC @return_value = [dbo].[UbaciVlasnika] @ImeVlasnika = @im, @PrezimeVlasnika = @pv, @DatumRodjenja = @dr, @JMBG = @jm, @VlasnikID = @VlasnikID OUTPUT;

SELECT @VlasnikID as VlasnikID, @return_value as ReturnValue

Обратите внимание, что вы пытаетесь вложить ~ 2 триллиона в целое число, максимальное значение которого составляет ~ 2 миллиарда


Отказ от ответственности: Для ясности, когда я сказал "должен выглядеть примерно так", я имею в видуРассматривать это как пример псевдокода - не то, чтобы это был идеальный идеальный код, который следует копировать прямо в вашу производственную систему.

Здесь я обращаю внимание на преобразование ваших данных в клиенте, не полагайтесь на неявное преобразование на сервере . Я специально не защищаю использование AddWithValue;AWV предоставляет отличный способ написать хороший, простой и понятный код параметризации для SqlCommand в качестве примера для SO, хотя он открывает ящик Pandora - подумайте, хотите ли вы его в производственной системе,Это менее важно для хранимых процедур, потому что тип параметра, который используется внутри процедуры, определяется в сигнатуре процедуры, а не выводится из типа, выведенного из .net-типа, передаваемого в AddWithValue, поэтому я более спокойно отношусь к его использованию с SP дляТочка, в которой я обычно не обращаю на это внимание, если только люди не начинают об этом говорить

0 голосов
/ 08 октября 2019

При выполнении этого через GUI вам необходимо использовать одинарные кавычки вокруг даты, которую вы вводите, например, '2019-10-08'.

Если вы посмотрите на код в результирующем редакторе запросов, вы 'Вы заметите, что если вы не добавите кавычки, это будет выглядеть примерно так:

@DatumRodjenja = 2019-10-08

Это приводит к "Неверному синтаксису рядом с" - ". ошибка.

Кроме того, значение, которое вы указали для параметра int, слишком велико для типа данных int, вам может потребоваться использовать bigint.

0 голосов
/ 08 октября 2019

Вы должны всегда перечислять имена столбцов, когда вы делаете INSERT:

ALTER PROC [dbo].[UbaciVlasnika] (
    @ImeVlasnika nvarchar (50),
    @PrezimeVlasnika nvarchar (50),
    @DatumRodjenja date,
    @JMBG int,
    @VlasnikID int OUTPUT
) AS
BEGIN
    INSERT INTO Vlasnik (ImeVlasnika, PrezimeVlasnika, DatumRodjenja, JMBG)
        VALUES (@ImeVlasnika, @PrezimeVlasnika, @DatumRodjenja, @JMBG);

    SELECT @VlasnikID = SCOPE_IDENTITY()
END;  -- UbaciVlasnika

Я предполагаю, что имена столбцов.

Очевидно, вы не вставляете ввсе столбцы, потому что один из них является столбцом идентификации. Я не уверен, почему вы не получаете сообщение об ошибке, указывающее, что у вас неверное количество значений параметров. Возможно, SQL Server проверяет типы, прежде чем подсчитает все значения.

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