SQL Server 日期格式不适用于存储过程

Posted

技术标签:

【中文标题】SQL Server 日期格式不适用于存储过程【英文标题】:SQL Server date format not working for stored procedure 【发布时间】:2013-05-11 20:08:21 【问题描述】:

我有一个更新表中一行的存储过程。 我正在使用 C# 将所有参数传递到存储过程中,如下所示:

public int editFestival(String festId, String festNaam, String festLocatie, String festDatum,
                        String festDuur, String festEindDatum, String festUrl)

sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["project"].ConnectionString);
sqlCommand = new SqlCommand("EditFestival", sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;

sqlCommand.Parameters.Add(new SqlParameter("@festId", Convert.ToInt32(festId)));
sqlCommand.Parameters.Add(new SqlParameter("@festNaam", festNaam));
sqlCommand.Parameters.Add(new SqlParameter("@festLocatie", festLocatie));
sqlCommand.Parameters.Add(new SqlParameter("@festDatum", Convert.ToDateTime(festDatum)));
                                 //Also tried ->       , SqlDbType.date)).Value = festDatum
sqlCommand.Parameters.Add(new SqlParameter("@festDuur", Convert.ToInt32(festDuur)));
sqlCommand.Parameters.Add(new SqlParameter("@festEindDatum", Convert.ToDateTime(festEindDatum)));
sqlCommand.Parameters.Add(new SqlParameter("@festUrl", festUrl));

sqlConnection.Open();
sqlTransaction = sqlConnection.BeginTransaction();
sqlCommand.Transaction = sqlTransaction;
rows = sqlCommand.ExecuteNonQuery();
sqlTransaction.Commit();
return rows;

虽然字符串 festDatum(在英语中表示 festDate)的格式正确(yyyy-MM-dd),但它不被存储过程接受。

当我使用自己给定的变量执行存储过程时,它会生成以下内容:

USE [groep2_festivals]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[EditFestival]
        @festId = 1,
        @festNaam = N'Rock Werchter',
        @festLocatie = N'Werchter - Belge',
        @festDatum = 2013-07-01, --This is where it says that there's a syntax error near '-'
        @festDuur = 4,
        @festEindDatum = 2013-07-04,
        @festUrl = N'www.rockwerchter.be'

SELECT  'Return Value' = @return_value

GO

当我用单引号手动将两个日期括起来时,它可以正常工作。 我究竟做错了什么?还是像用单引号将更新语句中的参数括起来一样简单?

编辑:这是原始存储过程(应该早点发布)

USE [groep2_festivals]
GO
/****** Object: StoredProcedure [dbo].[EditFestival] Script Date: 10/05/2013 12:44:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Robbie Vercammen
-- Create date: 10/05/2013
-- Description: Veranderd de gegevens van een bepaald festival
-- =============================================

CREATE PROCEDURE [dbo].[EditFestival]
    (
    @festId int,
    @festNaam nvarchar(255),
    @festLocatie nvarchar(255),
    @festDatum date,
    @festDuur int,
    @festEindDatum date,
    @festUrl nvarchar(255)
    )
AS
BEGIN
SET NOCOUNT ON;
UPDATE festivals
SET fest_naam = @festNaam, fest_locatie = @festLocatie, fest_datum = @festDatum,
    fest_duur = @festDuur, fest_einddatum = @festEindDatum, fest_url = @festUrl
WHERE fest_id = @festid
END

编辑:我正在尝试什么 我从管理工作室中执行存储过程

生成的代码已经在上面发布了;) 执行时它只是说

消息 102,第 15 级,状态 1,第 8 行 '-' 附近的语法不正确。

【问题讨论】:

你说 - “它不被存储过程接受。”。介意解释一下这是什么意思吗? 至于在 SSMS 中执行 SQL - 您需要在 SSMS 中使用日期文字。 2013-07-01 不是日期文字。请改用'2013-07-01'。这不是参数化版本(带日期)的问题。这假设您正在使用查询窗口来运行查询。 Convert.ToDateTime(festDatum) 真的会给你一个DateTime 类型的有效对象吗? 存储过程的@FestDataum@FestEindDatum 参数的类型是什么?我怀疑存储过程可能正在接受字符串参数并将它们转换为代码中的日期。 这看起来像是一个 SSMS 问题。与存储过程或您的 C# 无关。不确定它需要什么格式,但您可以尝试以下所有方法:'2013-07-01'01-Jul-2013#2013-07-01#。这是 SSMS 尝试将字符串转换为日期并失败。 【参考方案1】:

SQL 和 MSSQL Management Studio 中的日期文字需要用单引号括起来,除非使用了特定的整数日期格式,这里不是这种情况。

至于哪些格式可以工作...这将取决于托管数据库的机器上的区域设置。通常有几种不同的格式可以使用。 'yyyy-MM-dd' 经常使用,被广泛使用,从您发布的信息来看,似乎也适用于您的环境。

在 T-SQL 中,将 varchar 中的日期转换为日期/时间类型之一的最安全方法是尽可能使用 CONVERT() 函数,而不是将转换留给数据库。

但是,在 C# 中,通过 SqlCommand.Parameters 集合传递参数时不需要考虑单引号。当您选择正确的SqlDbType 时,报价会为您处理。如果您知道日期是特定格式,那么您应该解析日期参数并像这样传递它......

sqlCommand.Parameters.Add("@festDatum", SqlDbType.Date).Value = 
                          DateTime.ParseExact(festDatum, "yyyy-MM-dd", 
                                              CultureInfo.InvariantCulture);

festEindDatum 也一样。

如果您不以特定格式解析日期,那么您将把它留给 C# 或数据库根据本地机器的区域设置有效地猜测格式,当您的代码在不同的环境。

【讨论】:

你确定吗?在原帖中我已经说过:虽然字符串 festDatum 格式正确(yyyy-MM-dd)... 刚刚测试过,还是一样的错误信息。我认为问题不在于 c#,而在于存储过程本身【参考方案2】:

我看到的问题在于存储过程 @festDatum date, 中的数据类型是 date,而在您的 C# 代码 ("@festDatum", Convert.ToDateTime(festDatum) 中,您正在将其转换为 datetime

请尝试将存储过程中的参数类型从 date 转换为 datetime

在 c# 代码中使用 festDatum.ToShortDateString() 作为值。

如果有效,请告诉我。

【讨论】:

嗨,谢谢,我已经尝试过了,对我没有任何效果。但我刚刚将它转换为 nvarchar,它总是接受它。毕竟正确的日期格式是在c#中格式化然后发送到sp

以上是关于SQL Server 日期格式不适用于存储过程的主要内容,如果未能解决你的问题,请参考以下文章

VBA 将日期参数传递给 SQL Server 存储过程

如何在 SQL Server中 将日期格式化

将用户定义表中的日期值传递给 SQL Server 2008 存储过程

将 Access 表日期值作为参数传递给 SQL Server 存储过程

SQL Server:从最大日期/最新日期的记录中获取数据

sql server 数据库,在查询sql语句中日期格式转换问题,怎么把原数据年月日时分秒转换成年月日