【问题标题】:SQL INSERT using tables where the columns have different data types and getting error convertingSQL INSERT 使用列具有不同数据类型的表并获得错误转换
【发布时间】:2012-12-05 20:06:48
【问题描述】:

我有两张桌子,我想将一张桌子插入另一张桌子。在我的暂存(源)表中,每一列都定义为nvarchar(300),并且这个限制不能改变。

在我的目标表中,列是所有不同类型的。例如,如果我想从源表中选择(数据类型nvarchar(300))并将该列插入到decimal(28, 16) 的数据类型中。

发生这种情况时,我收到以下错误:

将数据类型 nvarchar 转换为数值时出错。

即使我使用演员表,我也会收到错误。

INSERT INTO Destination (
    Weighting
)
VALUES (
    CAST(src.Weighting AS decimal(28, 16))
)

null 的值会影响这个吗?还有什么要考虑的吗?

【问题讨论】:

  • 你确定它是一个可以强制转换的字符串吗?测试数字。

标签: sql-server tsql insert


【解决方案1】:

如果暂存表列中的所有数据都可以隐式转换为目标数据类型,那么您不必设置显式转换。

但如果任何一个值不能被隐式转换(即一个单元格包含一个非数字或格式错误的字符串值,该值应该以decimal 类型列结束),那么整个事务将失败。

您可以通过这样设置插入来转移失败事务的风险:

INSERT
  LiveTable (
    VarcharCol,
    DecimalCol,
    NonNullableCol
  )
SELECT
  NvarcharCol1,
  CASE ISNUMERIC(nvarcharCol2) = 0 THEN NvarcharColl2 END,
  ISNULL(NvarcharCol3, '')
FROM
  StagingTable

但这显然意味着丢失潜在相关数据或数值精度的风险。

您可以阅读 MSDN 上的which data types are implicitly convertible between each other(向下滚动到矩阵)。对于所有其他转换,您必须使用 CASTCONVERT

【讨论】:

    【解决方案2】:

    这将搜索非数字字符串

    select src.Weighting from src where isumeric(src.Weighting) = 0

    【讨论】:

    • 这很有帮助 - 我在查询中的所有列上运行它。原来Weighting 在列中有parent 的值。谢谢。
    • 然后在插入中添加一个 where isumeric(src.Weighting) = 1 用于可以转换的值。
    【解决方案3】:
    INSERT INTO Destination (Weighting)
    SELECT CAST(src.Weighting AS decimal(28, 16))
      FROM [Source] src
    

    应该可以正常工作,前提是您的 varchar 值格式正确。 如果错误仍然存​​在,请举例说明正在转换的值。

    NULL 将成功转换为 NULL。

    【讨论】:

      【解决方案4】:

      TSQL 具有您想要的类型的functions for casting or converting 数据。如果您在源中的数据类型严格地是您试图将它们存储在目标表中并且在目标表的规范中,那么您将不会遇到太多麻烦。

      如果您有一列数字,其中一个是“三”而不是“3”,它会变得复杂。 Here 是关于将 varchar 转换为小数的问题

      一个例子:我可以将 123 转换为 varchar(20),然后在适当的时候将 varchar 转换为十进制就没有问题了。

      SELECT cast(cast('123' as varchar(20)) as decimal(8,2))
      

      但是,如果我尝试转换字符,则会出错。

      SELECT cast(cast('1a3' as varchar(20)) as decimal(8,2))
      

      【讨论】:

        【解决方案5】:

        null只有在目标列不允许空值的情况下才有问题,我认为问题是格式字符串不能总是转换成小数,看看小数分隔符是逗号而不是点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-07-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-20
          • 1970-01-01
          相关资源
          最近更新 更多