我有两个表,我想从一个插入另一个表。在我的登台(源)表中,每个列定义为nvarchar(300)
,并且此限制不会改变。
在我的目标表中,这些列是所有不同类型的。例如,如果我想从源表(数据类型nvarchar(300)
)中进行选择,然后将列插入decimal(28, 16)
的数据类型。
发生这种情况时,我会收到以下错误:
错误将数据类型NVarchar转换为数字。
即使我使用铸件,也会得到错误。
INSERT INTO Destination (
Weighting
)
VALUES (
CAST(src.Weighting AS decimal(28, 16))
)
null
值可能会影响这一点吗?还有其他要考虑的吗?
如果您的登台表列中的所有数据都可以隐式转换为目标数据类型,那么您不必设置明确的铸件。
但是,如果无法隐式转换任何一个值(即一个单元格包含一个非数字或错误的字符串值,该值应该在decimal
类型列中结束),则整个交易将失败。
您可以通过设置这样的插入来迁移交易失败的风险:
INSERT
LiveTable (
VarcharCol,
DecimalCol,
NonNullableCol
)
SELECT
NvarcharCol1,
CASE ISNUMERIC(nvarcharCol2) = 0 THEN NvarcharColl2 END,
ISNULL(NvarcharCol3, '')
FROM
StagingTable
,但显然这意味着失去潜在相关数据或数字精度的风险。
您可以在MSDN上读取哪些数据类型在彼此之间隐式转换(向下滚动到矩阵)。对于所有其他转换,您必须使用CAST
或CONVERT
。
这将搜索非数字字符串
从src中选择src.tewighting,其中isnumeric(src.weighting)= 0
INSERT INTO Destination (Weighting)
SELECT CAST(src.Weighting AS decimal(28, 16))
FROM [Source] src
应该可以正常工作,只要您的varchar值以正确的格式。如果仍然发生错误,请给出一个被转换的值的示例。
nulls将成功转换为nulls。
tsql具有铸造或将数据转换为您想要的类型的功能。如果源中的数据类型严格来说是您试图像在目标表中以及在目标表的规格中一样将它们存储的内容,那么您不会遇到太多麻烦。
如果您有数字的一列,而IS"三"而不是" 3",则会变得复杂。这是将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))
null仅在目标列不允许零时是一个问题,我认为问题是无法始终转换为十进制的格式字符串,查看小数分隔符是否是逗号而不是点。