【问题标题】:Error Converting Data Type in Execute Procedure执行过程中转换数据类型时出错
【发布时间】:2019-06-20 17:16:12
【问题描述】:

我正在尝试运行将数据插入“表 A”的执行过程。对于一个特定参数,我将参数类型设置为“日期”以匹配“表 A”中“日期示例”列的数据类型。由于某种原因,系统将视图数据源“ViewExample”中的字段数据类型识别为 nvarchar,即使数据类型是日期。

我尝试将参数设置为 nvarchar,但收到以下错误:

Msg 241, Level 16, State 1, Procedure p_example, Line 34 [Batch Start Line 0]
Conversion failed when converting date and/or time from character string

代码:

ALTER Procedure [dbo].[p_example]
,   @DateExample date

AS 

begin

INSERT INTO [DatabaseEx].[dbo].[Table A]
           ([DateExample]

)

values (

    @DateExample


)

end

Select DISTINCT 
    D.DateExample
From DatabaseEx.dbo.ViewExample D

Where 1 = 1

GO



EXECUTE [dbo].[p_example]

    @DateExample = DateExample



GO

预期结果:数据将正确插入表中

当前结果:

Msg 8114, Level 16, State 1, Procedure p_example, Line 0 [Batch Start Line 0]
Error converting data type nvarchar to date.

【问题讨论】:

    标签: sql-server stored-procedures data-conversion


    【解决方案1】:

    TL;DR 在答案的末尾。

    以下是我的更改和建议方法的完整答案和理由。

    1.很长的路要走:

    我将对您的代码进行一些调整和调整:

    根据下面的定义,您的存储过程应该获得一个 single 类型为“日期”的值作为参数(到目前为止一切顺利)

    ALTER Procedure [dbo].[p_example]
        @DateExample date
    AS 
    begin
    

    您的插入查询采用@DateExample 参数并将其添加到[Table A],到目前为止一切顺利

    INSERT INTO [DatabaseEx].[dbo].[Table A]
               ([DateExample])
    values (@DateExample)
    
    end
    

    这似乎是您决定将哪些值传递给存储过程的部分。这是我发现第一个可能的问题的地方。

    Select DISTINCT 
        D.DateExample
    From DatabaseEx.dbo.ViewExample D
    Where 1 = 1
    

    您的SELECT DISTINCT 查询没有“定义”存储在"DateExample" 中的值,您可以稍后将其传递给存储过程。为了将该值存储在可以重复使用的位置,您需要将其存储到一个变量中(至少)。

    所以,我将上面的查询修改为:

    DECLARE @DateExample date;
    
    Select DISTINCT 
        @DateExample = D.DateExample
    From DatabaseEx.dbo.ViewExample D
    Where 1 = 1
    

    然而,这还不是全部。上述查询仍然会失败如果 SELECT DISTINCT 将返回超过 1 个值。

    SELECT DISTINCT 并不意味着返回单个唯一值,但是它将返回存储在 DateExample 列中的所有唯一值strong>DatabaseEx.dbo.ViewExample 视图。

    如果您只想将查询中的 1 个值传递给存储过程,或者如果您想将多个值传递给存储过程,则以下版本会更好。

    DECLARE @DateExampleTable TABLE (dateExample date);
    
    INSERT INTO @DateExampleTable (dateExample)
    Select DISTINCT 
        D.DateExample
    From DatabaseEx.dbo.ViewExample D
    Where 1 = 1
    

    这将涵盖所有内容,如果您的 SELECT DISTINCT 返回超过 1 行,您将不会收到任何错误。

    现在,您可能注意到变量名称和类型已从 DATE 更改为 TABLE。这要求我们也更改存储过程的代码,以便它接受这种新类型的参数。

    为了将更多行数据传递给我们的存储过程,我们首先必须创建一个新的表类型,我们将使用它来存储多行数据作为参数,以便我们以后可以将它传递给我们的存储程序。

    CREATE TYPE DateTableType AS TABLE (DateExample date);
    
    ALTER Procedure [dbo].[p_example]
        @DateExampleParam DateTableType READONLY
    AS 
    begin
    
    INSERT INTO [DatabaseEx].[dbo].[Table A]
               ([DateExample])
    SELECT DateExample
    FROM @DateExampleParam 
    
    end
    

    现在我们有了新版本的存储过程,

    EXECUTE [dbo].[p_example]
        @DateExampleParam = @DateTableExample
    

    2。 TL;DR 总结如下:

    现在,如果我们将我刚刚编写的所有内容汇总到一个重构脚本中,它将如下所示:

    CREATE TYPE DateTableType AS TABLE (DateExample date);
    GO    
    
    ALTER Procedure [dbo].[p_example]
        @DateExampleParam DateTableType READONLY
    AS 
    begin
    
    INSERT INTO [DatabaseEx].[dbo].[Table A]
               ([DateExample])
    SELECT DateExample
    FROM @DateExampleParam 
    
    end
    GO
    
    DECLARE @DateExampleTable TABLE (dateExample date);
    
    INSERT INTO @DateExampleTable (dateExample)
    Select DISTINCT 
        D.DateExample
    From DatabaseEx.dbo.ViewExample D
    Where 1 = 1
    
    EXECUTE [dbo].[p_example]
        @DateExampleParam = @DateExampleTable 
    

    【讨论】:

      【解决方案2】:

      这行会导致你得到的错误:

      EXECUTE [dbo].[p_example]
      
          @DateExample = DateExample
      

      DateExample 参数需要 date 数据类型,而您正尝试将其设置为“DateExample”。

      【讨论】:

        猜你喜欢
        • 2016-03-14
        • 1970-01-01
        • 2014-03-14
        • 2022-08-03
        • 1970-01-01
        • 2018-11-04
        • 2010-11-17
        • 2023-03-04
        • 1970-01-01
        相关资源
        最近更新 更多