存储过程插入日期格式的问题

时间:2019-10-08 15:10:07

标签: sql sql-server

我有一个存储过程,需要在表中插入日期。但是,当我尝试通过具有YYYY-MM-DD格式的图形界面执行它时,出现错误消息:

  

'-'附近的语法不正确。

我也尝试使用撇号,但是在将数值类型数字转换为整数时遇到错误。我检查了我的表是否格式正确,是否正确。知道发生了什么事吗?

string.length === 10

PS:我还尝试使用

插入值
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()

它正在工作。

3 个答案:

答案 0 :(得分:0)

在进行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在计算所有值之前会检查类型。

答案 1 :(得分:0)

问题实际上出在您的GUI中。代码实际上应该看起来像这样(例如使用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并专门在过程内转换日期-由于前面提到的有关前端知道的原因,我避免这样做/关注区域,本地化和文化等,而后端db可以/应该对这些事情一无所知

如果您使用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万亿个整数填充到一个整数中,该整数的最大值约为20亿


免责声明:为清楚起见,当我说“应该看起来像这样”时,我的意思是将其视为伪代码示例-并不是这是应该直接复制到生产系统中的理想代码。

这里我要指出的是在客户端中转换数据,而不是依靠服务器上的隐式转换。我不是特别提倡使用AddWithValue; AWV提供了一种绝佳的方式,可以为SqlCommand编写一些简洁,简单的参数化代码作为SO上的示例,尽管它自己打开了a Pandora's box-考虑是否要在生产系统中使用它。它与存储过程无关紧要,因为在过程内部使用的参数类型是在过程签名中定义的,而不是从传递给AddWithValue的.net类型推断的类型推断出来的,因此我对将其与SP一起用于我通常不会引起人们注意的地方,除非人们开始对此叉开脚步

答案 2 :(得分:0)

通过GUI执行此操作时,您需要在输入日期前后使用单引号,例如'2019-10-08'

如果查看结果查询编辑器中的代码,您会发现,如果不添加引号,它将类似于:

@DatumRodjenja = 2019-10-08

这会导致“'-'附近的语法不正确”。错误。

此外,对于int数据类型,您为int参数指定的值太大,您可能需要考虑使用bigint