我正在处理一些其他人写的一些问题(在我看来),他们在调用Convert()时完全包含了所有内容。
这些查询从源数据库获取数据,C#程序将该数据(使用System.Data.SqlClient.SqlBulkCopy)插入目标数据库中的表。
所以,这是我所看到的事物类型的缩写示例:
Select
Convert(nvarchar(50), t.Address1) as Address1
, Convert(smallint, case t.language_cd
when 'E' then 31
when 'N' then 32
when 'D' then 38
else 39
end) as LanguageID
from MyTable t
它转换为与目标表上的数据类型匹配的数据类型(目标表上的So Address1是nvarchar(50),LanguageID是smallint)。源列MyTable.Address1是varchar(60),对于LanguageID,您可以看到我们将文字31,32,38和39转换为smallint。
我的问题是:将每一列显式转换为与目标列匹配的数据类型是否有任何实际原因或优势?当然,将varchar(60)转换为nvarchar(50)可能会失败。但是将它包装在convert()中并不能阻止它失败。我想有一个优点是,如果确实发生了故障,那么很容易让人一眼就能看到(在查询文件中)我们正在尝试做的转换。但对我来说,这似乎并不能证明查询文件中的所有混乱,特别是像在Convert()调用中嵌入CASE语句这样丑陋的东西。另外,如果我们要更新目标数据库以将列延长到60个字符(可能是一个好主意但在短期内不可行),那么我们在Convert()调用和实际定义之间存在不匹配目标栏。
所以,我错过了一些理由,从我不知道的显式转换中得到的一些好处?或者是我的冲动是剥离这个查询并让转换发生隐含的好事?
答案 0 :(得分:2)
Microsoft recommends使用SqlBulkCopy时,源列和目标列类型匹配。而根据互联网,SqlBulkCopy并不像INSERT .. SELECT那样容忍不匹配的类型。所以我会说在查询中转换是个好主意。
更不用说类型转换并不总是直截了当或一致。例如,哪些数字转换轮次和哪些截断,并且所有转换规则在SQL Server中都是相同的(执行CONVERT的地方,或者如果这是INSERT .. SELECT将发生转换),因为它们适用于SqlBulkCopy (这与INSERT .. SELECT不一样)?如果您不确切知道规则是什么,那么谨慎是明智的。
此外,如果查询中的类型转换失败,您可能会获得比批量插入失败时更有用的错误消息。如果您希望这些查询更易于管理,可以这样写:
SELECT TOP (0)
CAST('' AS NVARCHAR(50)) AS Address1,
CAST(0 AS SMALLINT) AS LanguageID
UNION ALL
SELECT
t.Address1,
CASE t.language_cd
WHEN 'E' THEN 31
WHEN 'N' THEN 32
WHEN 'D' THEN 38
ELSE 39 END AS LanguageID
FROM MyTable t
这种重写很可能对查询优化没有影响(如果这是一个问题,请检查),虽然TOP不是标准SQL,但代码是来自CONVERT而不是CAST的特定于T-SQL的,所以开始时并不标准。
这里的优点是查询的内容不会混乱,并且宣布和强制执行目标表列类型的查询部分是完全独立的,这样可以在修改列类型时轻松更改。 / p>