如何使用hiveserver2从C#thrift.dll获取'null'值而不是字段列的默认值

时间:2015-08-24 08:37:40

标签: c# hive thrift thrift-protocol

我目前正在使用带有thrift.dll库的HiveServer2。如果我尝试从thrift对象创建一个元组,我希望未在对象中设置的字段在元组中标记为null。但是,默认值将被放入元组中。 E.g。

HqlConnection con = new HqlConnection("localhost", 10001, HiveServer.HiveServer2);    
con.Open();   
HqlCommand createCommand1 = new HqlCommand("select id,name,age,DOB,marks from engineer_list", con);   
createCommand1.ExecuteNonQuery();   
HqlDataReader reader = createCommand1.ExecuteReader();

预期输出应为

  

{(1,'John',24,2010-01-01 10:22:47,45.6),(2,null,null,null,null)}

但实际结果是:

  

{(1,'John',24,2010-01-01 10:22:47,45.6),(2 ,,, 0,0)}

当我们发送请求调用包含类型的NULL值的数字列(int,double,long,float ..)时,意味着thrift.dll本身返回为零而不是null或{{1 }}

对于字符串,时间戳类型平均值DBNull.value本身将返回为空字符串,而不是thrift.dllnull

通过分析DBNull.value的来源,我们按照

触发了读取列的方法

类: Thrift.Protocol.TBinaryProtocol

方法:默认情况下,ReadAll(缓冲区,偏移量,长度)返回为零。

说明:这将从thriftServer端口获取数据流

对于Int值跟随方法是调用,如果数据包含'null'

,则返回为'0'
thrift.dll

2 个答案:

答案 0 :(得分:0)

与Thrift无关:如果您将空的STRING存储到Hive中,那么在选择字段时您将获得一个空的STRING。如果您明确存储Null STRING,那么您将获得Null。 这是正确的DBMS应该工作的方式。

不幸的是,Oracle和SQL Server对VARCHAR数据类型有自己的愚蠢规则(即在Oracle中,Null可以显示为空字符串,反之亦然,如量子物理中的波形/粒子;以及SQL Server中的空字符串或多或少是一个带有空格的1个字符长的字符串。

如果您需要对空STRING进行应用程序级处理,请使用条件查询子句,例如CASE WHEN duh ='' THEN CAST(Null AS STRING) ELSE duh END

[编辑] 从不依赖于从STRING到数字数据类型的隐式转换。我同意,在那种情况下,Hive比其他数据库更糟糕。

CASE WHEN duh is Null OR duh ='' THEN CAST(Null AS SMALLINT) ELSE cast(duh as SMALLINT) END

PS:在某些版本的Hive中需要使用Nulls(特别是在V0.14中 - 从V0.13回归)

答案 1 :(得分:0)

检查空值字段。例如如果nulls [0] = 12.那么它的二进制值是" 1100",从右到左读取,这意味着最后两个值是acutally NULL值。