简体   繁体   English

动态 SQL 存储过程和日期时间

[英]Dynamic SQL stored procedure and datetime

I have a simple query that I want to convert to dynamic SQL.我有一个简单的查询,我想将其转换为动态 SQL。 I have 2 input parameters: a table and a datetime.我有 2 个输入参数:一个表格和一个日期时间。 And the output is the rowcount for the table and this specific datetime. output 是表的行数和这个特定的日期时间。

CREATE PROCEDURE [etl].[ROWCOUNT_TST2]
    (@P_LOAD_TARGET nvarchar(250),
     @P_LOAD_DATE DATETIME)
AS
BEGIN
    DECLARE @SQL nvarchar(1000)

    SET @SQL = 'SELECT COUNT(*) as Inserted FROM'+@P_LOAD_TARGET +' WHERE VALID_FROM ='''+  @P_LOAD_DATE+''' AND VALID_TO IS NULL'

    EXEC  (@SQL)
END;
GO

I tried different solutions.我尝试了不同的解决方案。 I tried the query with execute sp_executesql , I tied to add the the ''' before and after the @P_LOAD_DATE .我尝试使用执行sp_executesql进行查询,我绑定在@P_LOAD_DATE之前和之后添加'''。 I am probably missing something here.我可能在这里遗漏了一些东西。

When I execute the stored procedure with a table name and datetime like 2021-05-06 06:41:52.557 , I get the following error:当我使用表名和日期时间(如2021-05-06 06:41:52.557 )执行存储过程时,出现以下错误:

Conversion failed when converting date and/or time from character string.从字符串转换日期和/或时间时转换失败。

But why?但为什么?

I even tried to add a conversion to datetime like this, but I still get the same error.我什至尝试像这样添加对日期时间的转换,但我仍然遇到同样的错误。

 SET @SQL = 'SELECT COUNT(*) as Inserted FROM'+@P_LOAD_TARGET +' WHERE VALID_FROM = convert(datetime,'''+  @P_LOAD_DATE+''') AND VALID_TO IS NULL'

But when I execute SELECT convert(datetime, '2021-05-06 06:41:52.557') it works out fine.但是当我执行 SELECT convert(datetime, '2021-05-06 06:41:52.557') 它工作正常。 I am just confused right now and can't find the root of the problem.我现在很困惑,找不到问题的根源。

Edit: valid_from is a datetime in the target table.编辑: valid_from是目标表中的日期时间。 So that is also not the reason for the problem所以这也不是问题的原因

You need to properly and safely inject your dynamic object name and parametrise your parameter:您需要正确安全地注入您的动态 object 名称并参数化您的参数:

CREATE PROCEDURE [etl].[ROWCOUNT_TST2](@P_LOAD_SCHEMA sysname = N'dbo', --Always define your schema
                                       @P_LOAD_TARGET sysname, --sysname is the data type for objects, a synonym of nvarchar(128) NOT NULL
                                       @P_LOAD_DATE datetime) AS
BEGIN

    DECLARE @SQL nvarchar(MAX),
            @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

    SET @SQL = N'SELECT COUNT(*) AS Inserted' + @CRLF +
               N'FROM ' + QUOTENAME(@P_LOAD_SCHEMA) + N'.' + QUOTENAME(@P_LOAD_TARGET) + @CRLF +
               N'WHERE VALID_FROM = @P_LOAD_DATE' + @CRLF +
               N'  AND VALID_TO IS NULL;';

    --PRINT @SQL; --Your best friend.
    EXEC sys.sp_executesql @SQL, N'@P_LOAD_DATE datetime', @P_LOAD_DATE;

END;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM