Azure Data Factory中Salesforce日期格式不匹配致增量加载报错
问题背景
在Azure Data Factory中配置了从ADLS到Salesforce的增量加载复制任务:仅同步Salesforce中LastModifiedDate大于ADLS侧该字段最大值的记录。通过SQL控制表存储ADLS的最后更新水印日期,但运行管道时触发ODBC报错:
Failure happened on 'Source' side. ErrorCode=UserErrorUnclassifiedError,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Odbc Operation Failed.,Source=Microsoft.DataTransfer.ClientLibrary.Odbc.OdbcConnector,''Type=System.Data.Odbc.OdbcException,Message=ERROR [22018] [Microsoft][Support] (40550) Invalid character value for cast specification.,Source=Microsoft Salesforce ODBC Driver,'
两个Lookup活动返回的水印日期格式分别为:
- ADLS/SQL侧:
"ADLSWatermark": "2022-11-02T10:27:44.743Z" - Salesforce侧:
"SalesforceWatermarkvalueDT": "2022-11-03T09:45:50Z"
测试验证:使用带T和Z的ISO8601格式日期查询会报错,改为2022-11-02 10:27:44.743格式则运行正常。
解决方案
核心是将ADLS侧的水印日期转换为Salesforce ODBC驱动可识别的yyyy-MM-dd HH:mm:ss.fff格式,以下是三种可行方法:
方法1:在Lookup后用Set Variable转换格式
添加一个Set Variable活动,将Lookup获取的水印日期转换为目标格式,表达式示例:
formatDateTime(activity('Lookup_ADLS_Watermark').output.firstRow.ADLSWatermark, 'yyyy-MM-dd HH:mm:ss.fff')
后续复制活动的查询直接引用这个变量即可。
方法2:在SQL控制表查询时直接转换格式
修改Lookup活动的SQL查询语句,在查询阶段就输出符合要求的日期格式(以SQL Server为例):
SELECT CONVERT(varchar, ADLSWatermark, 121) AS ADLSWatermark FROM YourControlTable
注:CONVERT函数的121参数对应格式为yyyy-MM-dd HH:mm:ss.fff,刚好匹配需求。
方法3:直接在复制活动的查询中嵌入格式转换
在复制活动的源查询里直接用ADF表达式转换日期格式,示例:
SELECT * FROM Lead WHERE LastModifiedDate > '@{formatDateTime(activity('Lookup_ADLS_Watermark').output.firstRow.ADLSWatermark, 'yyyy-MM-dd HH:mm:ss.fff')}'
原理说明
Salesforce ODBC驱动对ISO8601标准的yyyy-MM-ddTHH:mm:ss.fffZ格式解析存在兼容性问题,无法正确将其转换为日期类型,因此需要转换为空格分隔的无时区后缀格式,才能避免类型转换错误。
内容的提问来源于stack exchange,提问作者rutgerv

