SQL Server ->> 内置标量函数TRY_PARSE、TRY_CAST和TRY_CONVERT的各自特点和区别

本文介绍了SQLServer 2014版本中新增的TRY_PARSE、TRY_CAST和TRY_CONVERT三个数据转换函数的特点及使用方法,并通过实例对比了这些函数与原有CAST和CONVERT函数的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL Server到了目前的2014版本有三个函数是用来转换数据格式的。虽说之前版本中已经有CAST和CONVERT这两个函数来干这个事情。问题是,一旦往目标数据类型转换失败就会造成报错。

TRY_PARSE、TRY_CAST和TRY_CONVERT的共同特点:

1)即便转换失败也不会造成整个语句报错,只会在无法转换的情况下输出NULL值;

 

TRY_PARSE:

TRY_PARSE是用于将字符串类型的数据转换成时间或者数值类型的数据。它是一个基于.NET CLR Runtime的标量函数。语法是TRY_PARSE(<string/string column> AS <data_type> [USING <culture>])

下面做一个字符串转时间的实验:

SQL Server 版本:

Microsoft SQL Server 2014
Enterprise Edition (64-bit) on Windows NT 6.3 <X64> 

SELECT TRY_PARSE('20150901' AS DATETIME), TRY_CAST('20150901' AS DATETIME), TRY_CONVERT(DATETIME,'20150901') 
SELECT TRY_PARSE('2015/09/01' AS DATETIME), TRY_CAST('2015/09/01' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01')
SELECT TRY_PARSE('2015/09/01 14:14:45' AS DATETIME), TRY_CAST('2015/09/01 14:14:45' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01 14:14:45')
SELECT TRY_PARSE('2015/09/01 14:14:45' AS DATETIME), TRY_CAST('2015/09/01 14:14:45' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01 14:14:45')
SELECT TRY_PARSE('2015/09/01 14:14:45+0001' AS DATETIME), TRY_CAST('2015/09/01 14:14:45+0001' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01 14:14:45+0001')

上面代码输出的结果如下图所示

可以看到TRY_PARSE在将纯数字转为DATETIME的情况下居然失效,这点让我非常意外,而且我尝试了DATE类型也是一样的结果。

而如果加了像"-"或者"/"这样的时间分隔符则三个函数都能转换成功。

还有一点让我惊讶的是TRY_CAST和TRY_CONVERT不支持带有时区的转换,而TRY_PARSE则可以。

而当我把第四行代码的冒号修改成中文下面的冒号时则SQL Server辨认不出来。

 

TRY_CAST和TRY_CONVERT:

这一对更多是CAST和CONVERT这对函数的变体,语法上一样,只是当无法成功转换的时候是报错或者输出NULL值。

 

三者的区别总结如下:

1)TRY_PARSE只支持字符转数值或者时间类型,而TRY_CAST和TRY_CONVERT支持更多的类型;

2)三者有一点比较好的就是对于字符的空格处理,只要空格在处在分割符号的前后像“2015/    09/   10”这样是可以被成功处理的,但是如果空格隔开本身就是一个整体的数据值部分,则全部不能识别,像“2015/0   9/10”。

2)TRY_PARSE由于是CLR写的函数,对于源数据的数据格式支持比较广或者要求比较宽松,而TRY_CAST和TRY_CONVERT则要求比较严格。这点从上面的例子中,TRY_PARSE支持带有时区的时间格式而其他两个不支持就可以看出。而TRY_PARSE的支持范围远不止于此。

下面这个例子就证明了TRY_PARSE是仅最大的努力和可能去转换数据,而后两者则需要很严格数据格式

SELECT TRY_PARSE('Thursday, 19 Nov 2015' AS DATETIME)  
SELECT TRY_CONVERT(DATETIME, 'Thursday, 19 Nov 2015'); 

 

 

-------------------------------------- update 2015/12/09 ----------------------------------------------

TRY_PARSE和TRY_CAST在把字符转换成数值这一功能上,TRY_PARSE在某种情况下要比TRY_CAST差。这里做个实验。

SELECT  Column1, 
        TRY_CAST(Column1 AS FLOAT) AS TRY_CAST, 
        TRY_CAST(REPLACE(Column1,',','') AS FLOAT) AS TRY_CAST_REMOVE_COMMA, 
        TRY_PARSE(Column1 AS FLOAT) AS TRY_PARSE, 
        TRY_PARSE(REPLACE(Column1,',','') AS FLOAT) AS TRY_PARSE_REMOVE_COMMA   
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0'
                ,'Excel 12.0 Xml;HDR=YES;IMEX=1;Database=D:\1.xlsx'
                ,'SELECT * FROM [sheet1$]');

上面语句的结果

 

我的源文件内容是这样的:

Column1
123,456
123456.789
123456
2,464
   210,860 
ABC

 

 

 

 

 

 

 

 

可以看到结果中对于第5行的转换TRY_PARSE没能把数字前后类似于空格的特殊字符忽略。这点上TRY_CAST应该说做得更加好。

转载于:https://www.cnblogs.com/jenrrychen/p/4976429.html

<think>好的,我现在需要帮助用户理解扩展卡尔曼滤波器(EKF)的代码实现,特别是变量Now_P、LastP、Kg、out的更新逻辑。首先,用户提供的参考代码是一维卡尔曼滤波器的实现,但用户的问题是关于扩展卡尔曼滤波器的,所以需要指出两者的不同,同时解释清楚变量在EKF中的角色。 首先,我应该回顾卡尔曼滤波(KF)扩展卡尔曼滤波(EKF)的区别。KF适用于线性系统,而EKF通过线性化处理非线性系统。因此,EKF的代码实现中会有雅可比矩阵的计算,状态转移函数观测函数的线性化步骤。但用户提供的示例代码是KF的一维版本,可能没有这些部分,需要说明这一点,并基于此进行扩展。 接下来,用户提到的变量Now_P、LastP、Kg、out在EKF中的含义: - Now_P:当前时刻的预测协方差矩阵(在KF中是标量- LastP:上一时刻的后验协方差矩阵 - Kg:卡尔曼增益 - out:状态估计值 在EKF中,变量更新步骤会更复杂,因为涉及到状态转移矩阵F观测矩阵H的雅可比矩阵,以及可能的过程噪声Q观测噪声R的矩阵形式。需要分步骤解释预测更新阶段。 预测阶段: 1. 状态预测:使用非线性状态转移函数f,得到预测状态。 2. 协方差预测:使用状态转移雅可比矩阵F,更新协方差矩阵P。 更新阶段: 1. 计算卡尔曼增益K:涉及预测协方差、观测雅可比矩阵HR。 2. 状态更新:结合预测观测值,使用非线性观测函数h。 3. 协方差更新:使用卡尔曼增益观测矩阵H。 用户提供的代码是线性的,没有雅可比矩阵,所以需要指出EKF需要这些额外的步骤。同时,变量Now_PLastP在代码中是标量,但在EKF中是矩阵,可能需要动态内存分配或固定大小的数组来处理多维状态。 用户可能对EKF的具体实现步骤不太清楚,需要详细解释每个变量的更新公式,并与KF对比。例如,KF中的预测协方差是P = LastP + Q,而EKF中是P = F * LastP * F^T + Q,其中F是雅可比矩阵。 另外,代码中的Kg计算在KF中是标量除法,但在EKF中是矩阵运算,涉及逆矩阵。需要说明在EKF中卡尔曼增益K的计算公式为K = P_pred * H^T * (H * P_pred * H^T + R)^{-1},这里H是观测模型的雅可比矩阵。 还要注意,用户提供的示例代码中的变量名可能与EKF中的标准变量名不同,需要对应起来,例如Now_P对应预测协方差P_pred,Last_P对应后验协方差P_post等。 可能用户需要了解代码中的变量如何对应到数学公式,因此需要将代码中的每一步与EKF的数学步骤对应起来,但用户提供的代码是KF,所以需要指出差异,并说明在EKF中的实现方式。 最后,用户可能需要示例代码或伪代码来理解EKF的实现,但由于EKF涉及矩阵运算线性化,代码会更复杂。可能需要建议用户参考多维的EKF实现示例,或者提供伪代码步骤。 总结回答结构: 1. 解释EKF与KF的区别,特别是线性化步骤。 2. 分步骤说明预测更新阶段,每个阶段涉及的变量公式。 3. 将用户提到的变量Now_P、LastP、Kg、out对应到EKF的数学公式中。 4. 指出用户提供的代码是KF,而EKF需要额外处理雅可比矩阵等。 5. 提供相关问题,帮助用户深入理解。</think>以下是对扩展卡尔曼滤波器(EKF)代码实现及变量更新逻辑的详细解析: ### 一、EKF与KF的核心差异 扩展卡尔曼滤波器通过局部线性化处理非线性系统,核心差异体现在: 1. 状态转移矩阵 $F$ 观测矩阵 $H$ 需通过雅可比矩阵计算[^1] 2. 协方差矩阵运算需考虑线性化误差 3. 状态预测观测需使用非线性函数 $f(x)$ $h(x)$ $$x_k = f(x_{k-1}) + w_k$$ $$z_k = h(x_k) + v_k$$ ### 二、变量作用及更新公式 | 变量名 | 数学符号 | 物理意义 | EKF更新公式 | |--------|----------|----------|-------------| | `LastP` | $P_{k-1}^+$ | 上一时刻后验误差协方差 | 初始值需设定 | | `Now_P` | $P_k^-$ | 当前时刻先验误差协方差 | $P_k^- = F_k P_{k-1}^+ F_k^T + Q$ | | `Kg` | $K_k$ | 卡尔曼增益矩阵 | $K_k = P_k^- H_k^T (H_k P_k^- H_k^T + R)^{-1}$ | | `out` | $\hat{x}_k^+$ | 后验状态估计 | $\hat{x}_k^+ = \hat{x}_k^- + K_k(z_k - h(\hat{x}_k^-))$ | ### 三、代码实现关键步骤 ```c // 注:以下为多维EKF伪代码逻辑 void ekf_update(struct EKF* ekf, float measurement) { // 1. 状态预测(非线性) ekf->x_pred = f(ekf->x_est); // 2. 协方差预测(线性化) Matrix F = compute_jacobian_f(ekf->x_est); ekf->P_pred = F * ekf->P_est * transpose(F) + ekf->Q; // 3. 计算卡尔曼增益 Matrix H = compute_jacobian_h(ekf->x_pred); Matrix K = ekf->P_pred * transpose(H) * inverse(H * ekf->P_pred * transpose(H) + ekf->R); // 4. 状态更新(非线性观测) ekf->x_est = ekf->x_pred + K * (measurement - h(ekf->x_pred)); // 5. 协方差更新 ekf->P_est = (I - K * H) * ekf->P_pred; } ``` ### 四、变量更新要点说明 1. **协方差矩阵传播** - 通过雅可比矩阵 $F$ 实现非线性系统的线性近似 - 过程噪声 $Q$ 需根据系统特性调参 2. **卡尔曼增益计算** - 矩阵求逆操作需保证数值稳定性 - 观测噪声 $R$ 增大时,$K$ 会减小,更信任预测值 3. **状态更新** - 创新量 $(z_k - h(\hat{x}_k^-))$ 反映测量残差 - 当系统高度非线性时需结合Unscented Kalman Filter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值