我有一个存储过程,需要在表中插入日期。但是,当我尝试通过具有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()
它正在工作。
答案 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
。