C# 如何在T-SQL中将日期时间字段与字符串连接起来

C# 如何在T-SQL中将日期时间字段与字符串连接起来,c#,sql-server,tsql,stored-procedures,.net-4.5,C#,Sql Server,Tsql,Stored Procedures,.net 4.5,我有一个动态查询,我正在尝试使用sp_executesql执行它。在动态查询中,我有一个datetime类型的字段。此字段作为参数从C.NET传递到SQL Server中的存储过程。我使用典型命令从C调用此sp: public static object ExecuteProcedure(int userId, DbConnection con, DbTransaction trans, string procedureName, bool withLog, params MyCusto

我有一个动态查询,我正在尝试使用sp_executesql执行它。在动态查询中,我有一个datetime类型的字段。此字段作为参数从C.NET传递到SQL Server中的存储过程。我使用典型命令从C调用此sp:

    public static object ExecuteProcedure(int userId, DbConnection con, DbTransaction trans, string procedureName, bool withLog, params MyCustomParameter[] parameters)
    {
        if (con.State != ConnectionState.Open)
            con.Open();

        bool bMyTransaction = trans == null;
        if (trans == null)
            trans = con.BeginTransaction();

        try
        {
            MyLog log = withLog ? MyLog.FromProcedure(trans, procedureName, parameters) : null;

            DbCommand command = con.CreateCommand();
            command.CommandType = System.Data.CommandType.StoredProcedure;
            command.CommandText = procedureName;
            command.Transaction = trans;
            command.AddMyCustomParameters(parameters);

            int result = command.ExecuteNonQuery();

            if (log != null)
                log.SaveLogData();

            if (bMyTransaction == true)
                trans.Commit();
            return result;
        }
        catch (Exception ex)
        {
            if (bMyTransaction == true)
                trans.Rollback();
            return null;
        }
    }
它在行中抛出一个异常:

int result = command.ExecuteNonQuery();
引发的错误是从西班牙语翻译过来的:

转换日期和/或时间中的字符串时出错

存储过程如下所示:

CREATE PROCEDURE [dbo].[spLogger]   
    @Id varchar(100),
    @Param1 varchar(100),
    @Param2 varchar(15),
    @Param3 int,
    @DateTimeField datetime,
    @Param4 varchar(100),
    @TargetTable tinyint = 0
AS
BEGIN
    DECLARE @sqlCommand nvarchar(max)
    DECLARE @tblName nvarchar(100)  

    SET @tblName = CASE @TargetTable 
                     WHEN 0 THEN '[dbo].[LogTable_01]'
                     WHEN 1 THEN '[dbo].[LogTable_02]'
                     WHEN 2 THEN '[dbo].[LogTable_03]'
                     ELSE ''
                  END

    IF @tblName <> ''
    BEGIN
        SET @sqlCommand =
        'INSERT INTO ' + @tblName +
                   '([Id] ' +
                   ',[Param1] ' +
                   ',[Param2] ' +
                   ',[Param3] ' +
                   ',[MyDateTimeField] ' +
                   ',[Param4]) ' +
             'VALUES' +
                   '(''' + @Id  + ''',''' + @Param1 + ''',''' + @Param2 + ''',' + CAST(@Param3 AS VARCHAR(10)) + ',' + @DateTimeField + ',''' + @Param4 + ''')'

        EXECUTE sp_executesql @sqlCommand
    END    
END
参数@DateTimeField是从C传递的,类型为DateTime。为此参数传递的值如下所示:

2020年2月27日18:05:05

在表中,MyDateTimeField定义为datetime

那么,如何将T-SQL中的datetime字段连接到字符串

正如您所看到的,我连接了一个INT类型,参数@Param3,我也想知道我是否也连接了ok

select a.a, FORMAT(a.a,'dd/MM/yyyy h:mm:ss tt') 
from
 (select convert(datetime, '2020-02-27 12:30:00' ) as a) a
输出:

2020-02-27 12:30:00.000 27/02/2020 12:30:00 PM

这显示了如何将日期时间转换为字符串,您可以使用该字符串连接到@sqlCommand;它们是参数。您需要通过将它们作为参数添加到sys.sp_executesql来对它们进行参数化。这样就不会出现连接日期时间的问题,因为实际上传递的是日期时间数据类型:

创建过程[dbo]。[spLogger] @Id varchar100, @Param1 varchar100, @Param2 varchar15, @参数3 int, @datetime字段datetime, @Param4 varchar100, @目标tinyint=0 像 开始 声明@sqlCommand-nvarcharmax; 声明@CRLF nchar2=NCHAR13+NCHAR10-这有助于格式化 声明@tblName sysname-已更改为正确的数据类型 设置@tblName=CASE@TargetTable 当为0时,则N'LogTable_01' 当1时,则N'LogTable_02' 当2时,则N'LogTable_03' 终止 如果@tblName不为NULL 开始 设置@sqlCommand=N“插入到dbo中”。+QUOTENAME@tblName+'[Id]'+@CRLF+ N',[Param1]'+@CRLF+ N',[Param2]'+@CRLF+ N',[Param3]'+@CRLF+ N',[MyDateTimeField]'+@CRLF+ N',[Param4]'+@CRLF+ N'值@Id、@Param1、@Param2、@Param3、@DateTimeField、@Param4;'L -PRINT@SQL-你的朋友。 执行sys.sp_executesql@sqlCommand,N'@Id varchar100、@Param1 varchar100、@Param2 varchar15、@Param3 int、@DateTimeField datetime、@Param4 varchar100'、@Id、@Param1、@Param2、@Param3、@DateTimeField、@Param4; 终止 终止
您以前是否尝试过转换日期时间,然后是concat?您不需要连接它,应该将它们与sp_executesql一起传递。如果你做得对,这就不会成为问题。@iakobski不,OP需要参数化。@Larnu我觉得有些人不看评论。@đxě非常感谢你的想法。我已经照你说的做了,拉穆也以同样的方式回答了下面的问题。现在它起作用了!!!!!!!!非常感谢!!!!!!!这不是一个答案,是的,但不是OP需要的,对IMHO没有帮助。@đěxěŕ:我试图回答:那么我如何将t-SQL中的datetime字段连接到字符串?然后解释一下,这是如何将datetime连接到字符串中的;它是动态的。它不是动态的,是一个名为@DateTimeField的输入参数,非常固定……QUOTENAME这背后的原因是什么,TBH,我以前从未见过这样做@đěxěŕ。TL;DR It确保对象名称的安全注入。很惊讶你没有看到我的另一个答案使用它读起来很棒,很有趣,很有意义。谢谢你的反馈,是的,我很惊讶我还没有看到这一点;第一次,谢谢。我倾向于将任何需要注入QUOTENAME的对象包装起来,不管它是否来自安全的源。它只是未来的证明,当目标帖子移动时,任何代码都应该这样做,而且如果你有一个对象名称,其中包含一个]因为人们很愚蠢,并且确实创建了它们>\u<,那么它也只会保证事情的安全和工作。感谢Lamu提供了一个很好的例子。你救了我一天;它就像一个符咒!关于QUOTENAME的另一篇有趣的文章。我不知道。伟大的