当前位置: 首页 > news >正文

校园网站建设培训简讯凡客诚品商城

校园网站建设培训简讯,凡客诚品商城,长沙平台搭建公司,网站开发招标前言 大概故事是这样的#xff0c;PostgreSQL数据库#xff0c;表结构#xff1a; create table t1(a varchar);然后使用标准的Java jdbc去插入数据#xff0c;其基本代码如下#xff1a; import java.sql.*; public class PgDoubleTest {public static void main(Stri… 前言 大概故事是这样的PostgreSQL数据库表结构 create table t1(a varchar);然后使用标准的Java jdbc去插入数据其基本代码如下 import java.sql.*; public class PgDoubleTest {public static void main(String[] args) {Connection connection  null;ResultSet resultSet  null;PreparedStatement ps null;try {// 连接到数据库connection  DriverManager.getConnection(jdbc:postgresql://192.168.0.6:5432/mydb, mydb, test123);String sqlinsert into t1 values(?);ps  connection.prepareStatement(sql);ps.setObject(1,new Double(48));ps.execute();ps.setObject(1,new Double(48.1));ps.execute();ps.setObject(1,new Double(48.9));ps.execute();} catch (SQLException e) {e.printStackTrace();} finally {try {if (ps ! null) {ps.close();}if (connection ! null) {connection.close();}} catch (SQLException e) {e.printStackTrace();}}} }发现 PostgreSQL11和12及以后的版本插入到表t1中的记录值不一样。 PG11中的结果 mydb# select * from t1;a ---------------------4848.100000000000001448.8999999999999986 (3 rows)PG12及后续版本的结果 mydb# select * from t1;a ------4848.148.9 (3 rows)这个问题如何分析 分析 上边的Java代码片段采用的都是完全相同的jdbc driver: dependencygroupIdorg.postgresql/groupIdartifactIdpostgresql/artifactIdversion42.7.3/version/dependency有几种可能性驱动层根据服务器端不同的版本发送的数据就完全不同。或者服务器端根据客户端来的数据处理有所不同。 检查下SQL日志 我们分别打开postgresql.conf开启记录所有的SQL log_statement all # none, ddl, mod, all 于是看到PG11的日志是这样的 2024-03-30 11:20:46.235 CST [13553] LOG:  execute unnamed: SET extra_float_digits  3 2024-03-30 11:20:46.236 CST [13553] LOG:  execute unnamed: SET application_name  PostgreSQL JDBC Driver 2024-03-30 11:20:46.262 CST [13553] LOG:  execute unnamed: insert into t1 values($1) 2024-03-30 11:20:46.262 CST [13553] DETAIL:  parameters: $1  48 2024-03-30 11:20:46.265 CST [13553] LOG:  execute unnamed: insert into t1 values($1) 2024-03-30 11:20:46.265 CST [13553] DETAIL:  parameters: $1  48.1000000000000014 2024-03-30 11:20:46.266 CST [13553] LOG:  execute unnamed: insert into t1 values($1) 2024-03-30 11:20:46.266 CST [13553] DETAIL:  parameters: $1  48.8999999999999986 2024-03-30 11:21:11.696 CST [13555] LOG:  statement: select * from t1;而PG12的日志是这样的 2024-03-30 10:45:30.172 CST [2700] LOG:  execute unnamed: SET extra_float_digits  3 2024-03-30 10:45:30.173 CST [2700] LOG:  execute unnamed: SET application_name  PostgreSQL JDBC Driver 2024-03-30 10:45:30.197 CST [2700] LOG:  execute unnamed: insert into t1 values($1) 2024-03-30 10:45:30.197 CST [2700] DETAIL:  parameters: $1  48 2024-03-30 10:45:30.199 CST [2700] LOG:  execute unnamed: insert into t1 values($1) 2024-03-30 10:45:30.199 CST [2700] DETAIL:  parameters: $1  48.1 2024-03-30 10:45:30.200 CST [2700] LOG:  execute unnamed: insert into t1 values($1) 2024-03-30 10:45:30.200 CST [2700] DETAIL:  parameters: $1  48.9也就是说到了服务器端绑定参数值的时候就已经不同了。PG11里头传的字符串值已经有了变化了。很有意思的东西。我们不忙着下结论。 既然Server端的log不能判定我们可以看看driver层的详细的log信息。这个需要设置logging.properties. 详情可以参考文档https://jdbc.postgresql.org/documentation/logging/ 查看JDBC客户端driver层日志 PG12的相关日志有如下关键内容 三月 31, 2024 3:49:55 下午 org.postgresql.Driver connect 详细: Connecting with URL: jdbc:postgresql://192.168.0.6:5555/mydb?loggerLevelTRACEloggerFilejdbc.log 三月 31, 2024 3:49:55 下午 org.postgresql.jdbc.PgConnection init 详细: PostgreSQL JDBC Driver 42.7.3 三月 31, 2024 3:49:55 下午 org.postgresql.jdbc.PgConnection setDefaultFetchSize 详细:   setDefaultFetchSize  0非常详细:  BE ParameterStatus(server_version  12.11) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveParameterStatus 非常详细:  BE ParameterStatus(session_authorization  mydb) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveParameterStatus 非常详细:  BE ParameterStatus(standard_conforming_strings  on) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveParameterStatus 非常详细:  BE ParameterStatus(TimeZone  Asia/Shanghai) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl readStartupMessages 非常详细:  BE BackendKeyData(pid8,855,ckey-1,722,642,031) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveRFQ 非常详细:  BE ReadyForQuery(I) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl execute 非常详细:   simple execute, handlerorg.postgresql.core.SetupQueryRunner$SimpleResultHandler614ddd49, maxRows0, fetchSize0, flags1,047 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendParse 非常详细:  FE Parse(stmtnull,querySET extra_float_digits  3,oids{}) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind 非常详细:  FE Bind(stmtnull,portalnull) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendExecute 非常详细:  FE Execute(portalnull,limit1) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendSync 非常详细:  FE Sync 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE ParseComplete [null] 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE BindComplete [unnamed] 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveCommandStatus 非常详细:  BE CommandStatus(SET) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveRFQ 非常详细:  BE ReadyForQuery(I) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl execute 非常详细:   simple execute, handlerorg.postgresql.core.SetupQueryRunner$SimpleResultHandler711f39f9, maxRows0, fetchSize0, flags1,047 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendParse 非常详细:  FE Parse(stmtnull,querySET application_name  PostgreSQL JDBC Driver,oids{}) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind .... 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveRFQ 非常详细:  BE ReadyForQuery(I) 三月 31, 2024 3:49:55 下午 org.postgresql.jdbc.PgConnection init 非常详细:     types using binary send  OID_ARRAY,UUID,BYTEA,INT8,INT2,INT4,POINT,TIMESTAMP,BOX,TIMESTAMPTZ,NUMERIC,BYTEA_ARRAY,INT2_ARRAY,INT4_ARRAY,TEXT_ARRAY,TIMETZ,VARCHAR_ARRAY,INT8_ARRAY,TIME,FLOAT4,FLOAT8,FLOAT4_ARRAY,FLOAT8_ARRAY 三月 31, 2024 3:49:55 下午 org.postgresql.jdbc.PgConnection init 非常详细:     types using binary receive  OID_ARRAY,UUID,BYTEA,INT8,INT2,INT4,POINT,TIMESTAMP,BOX,TIMESTAMPTZ,NUMERIC,BYTEA_ARRAY,INT2_ARRAY,INT4_ARRAY,TEXT_ARRAY,TIMETZ,VARCHAR_ARRAY,INT8_ARRAY,DATE,TIME,FLOAT4,FLOAT8,FLOAT4_ARRAY,FLOAT8_ARRAY 三月 31, 2024 3:49:55 下午 org.postgresql.jdbc.PgConnection init 非常详细:     integer date/time  true 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl execute 非常详细:   simple execute, handlerorg.postgresql.jdbc.PgStatement$StatementResultHandler2353b3e6, maxRows0, fetchSize0, flags17 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendParse 非常详细:  FE Parse(stmtnull,queryinsert into t1 values($1),oids{701}) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind 非常详细:  FE Bind(stmtnull,portalnull,$1(48.0::double precision),typeFLOAT8) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendDescribePortal 非常详细:  FE Describe(portalnull) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendExecute 非常详细:  FE Execute(portalnull,limit0) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendSync 非常详细:  FE Sync 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE ParseComplete [null] 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE BindComplete [unnamed] 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE NoData 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveCommandStatus 非常详细:  BE CommandStatus(INSERT 0 1) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveRFQ 非常详细:  BE ReadyForQuery(I) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl execute 非常详细:   simple execute, handlerorg.postgresql.jdbc.PgStatement$StatementResultHandler42f93a98, maxRows0, fetchSize0, flags17 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendParse 非常详细:  FE Parse(stmtnull,queryinsert into t1 values($1),oids{701}) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind 非常详细:  FE Bind(stmtnull,portalnull,$1(48.1::double precision),typeFLOAT8) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendDescribePortal 非常详细:  FE Describe(portalnull) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendExecute 非常详细:  FE Execute(portalnull,limit0) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendSync 非常详细:  FE Sync 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE ParseComplete [null] 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE BindComplete [unnamed] 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE NoData 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveCommandStatus 非常详细:  BE CommandStatus(INSERT 0 1) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl receiveRFQ 非常详细:  BE ReadyForQuery(I) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl execute 非常详细:   simple execute, handlerorg.postgresql.jdbc.PgStatement$StatementResultHandlerc46bcd4, maxRows0, fetchSize0, flags17 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendParse 非常详细:  FE Parse(stmtnull,queryinsert into t1 values($1),oids{701}) 三月 31, 2024 3:49:55 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind 非常详细:  FE Bind(stmtnull,portalnull,$1(48.9::double precision),typeFLOAT8)我们看到上边有明显的 非常详细:  BE ParameterStatus(server_version  12.11) 非常详细:  FE Bind(stmtnull,portalnull,$1(48.0::double precision),typeFLOAT8) 非常详细:  FE Bind(stmtnull,portalnull,$1(48.1::double precision),typeFLOAT8) 非常详细:  FE Bind(stmtnull,portalnull,$1(48.9::double precision),typeFLOAT8) FE Parse(stmtnull,querySET extra_float_digits  3,oids{})再看看PG11下边的详细日志 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl receiveParameterStatus 非常详细:  BE ParameterStatus(server_version  11.22 [by Sean]) 。。 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind 非常详细:  FE Bind(stmtnull,portalnull,$1(48.0::double precision),typeFLOAT8) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendDescribePortal 非常详细:  FE Describe(portalnull) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendExecute 非常详细:  FE Execute(portalnull,limit0) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendSync 非常详细:  FE Sync 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE ParseComplete [null] 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE BindComplete [unnamed] 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE NoData 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl receiveCommandStatus 非常详细:  BE CommandStatus(INSERT 0 1) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl receiveRFQ 非常详细:  BE ReadyForQuery(I) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl execute 非常详细:   simple execute, handlerorg.postgresql.jdbc.PgStatement$StatementResultHandler42f93a98, maxRows0, fetchSize0, flags17 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendParse 非常详细:  FE Parse(stmtnull,queryinsert into t1 values($1),oids{701}) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind 非常详细:  FE Bind(stmtnull,portalnull,$1(48.1::double precision),typeFLOAT8) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendDescribePortal 非常详细:  FE Describe(portalnull) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendExecute 非常详细:  FE Execute(portalnull,limit0) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendSync 非常详细:  FE Sync 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE ParseComplete [null] 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE BindComplete [unnamed] 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl processResults 非常详细:  BE NoData 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl receiveCommandStatus 非常详细:  BE CommandStatus(INSERT 0 1) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl receiveRFQ 非常详细:  BE ReadyForQuery(I) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl execute 非常详细:   simple execute, handlerorg.postgresql.jdbc.PgStatement$StatementResultHandlerc46bcd4, maxRows0, fetchSize0, flags17 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendParse 非常详细:  FE Parse(stmtnull,queryinsert into t1 values($1),oids{701}) 三月 31, 2024 3:59:17 下午 org.postgresql.core.v3.QueryExecutorImpl sendBind 非常详细:  FE Bind(stmtnull,portalnull,$1(48.9::double precision),typeFLOAT8)找出关键的几行 非常详细:  BE ParameterStatus(server_version  11.22 [by Sean]) 非常详细:  FE Bind(stmtnull,portalnull,$1(48.0::double precision),typeFLOAT8) 非常详细:  FE Bind(stmtnull,portalnull,$1(48.1::double precision),typeFLOAT8) 非常详细:  FE Bind(stmtnull,portalnull,$1(48.9::double precision),typeFLOAT8) FE Parse(stmtnull,querySET extra_float_digits  3,oids{})比较后的总结、模拟重现与深挖 从驱动层来看发送过去的内容或指令应该是一样的。只是Server端对于类似于如下的binding分别有精度损失或没有精度损失 $1(48.1::double precision),typeFLOAT8) 我们看看PG11下边的一些行为 show extra_float_digits;extra_float_digits --------------------0 (1 row)select 48.1::float8;float8 --------48.1 (1 row)SET extra_float_digits  3; SET mydb# select 48.9::float8;float8 ---------------------48.8999999999999986 (1 row) 看到了吗在extra_float_digits 3;时结果就出来了。48.8999999999999986 而到了PG12结果是这样 mydb# show extra_float_digits;extra_float_digits --------------------1 (1 row)mydb# select 48.1::double precision;float8 --------48.1 (1 row)mydb# SET extra_float_digits  3; SET mydb# select 48.1::double precision;float8 --------48.1 (1 row)所以 从上边的分析来看是server端对于extra_float_digits 3时在字符串转到float8 (double precision)时的行为不一样导致的。 至此真相大白。 我们也可以看下参数extra_float_digits的真实含义 https://postgresqlco.nf/doc/zh/param/extra_float_digits/ Sets the number of digits displayed for floating-point values 这个参数调整用于文本输出浮点值的位数包括float4float8以及几何数据类型。 如果值为1(默认值)或更高浮点值被输出为最短-精度格式参见datatype-float。实际生成的位数只取决于输出的值而不取决于此参数的值。float8 值最多需要 17 位数字float4值最多需要9位数字。这种格式既快速又精确在正确读取时精确地保留了原始的二进制浮点值。为了历史兼容性允许的值最大为3。 如果值为零或负则输出四舍五入为给定的十进制精度。使用的精度是根据此参数的值减小的类型(FLT_DIG或DBL_DIG视情况而定的标准位数。例如指定 -1 将导致float4 值输出四舍五入为 5 位有效数字而float8值四舍五入为 14 位。 此格式较慢不会保留二进制浮点值的所有位但可能令人更易于阅读。 此参数的含义以及其默认值在 PostgreSQL 12 中发生了变化; 参见 datatype-float 以便进一步讨论。 我在PostgreSQL, 留心对应的BigDecimal,Float,Double几种Java类型也有关于float8类型的详细介绍 。 总结 分析这类问题在源码介入之前通过两端的日志进行对比分析往往也能抓到蛛丝马迹。进而可以进一步进行挖掘和分析。上边的Java代码最后都可以通过简单的SQL片段来重现。 参考 https://www.enterprisedb.com/blog/jdbc-logging-using-javautillogging https://jdbc.postgresql.org/documentation/logging/ https://postgresqlco.nf/doc/zh/param/extra_float_digits/
http://www.w-s-a.com/news/403570/

相关文章:

  • 珠海斗门建设局网站如何免费做网站
  • 自助外贸网站建设可直接打开网站的网页
  • 江苏城嘉建设工程有限公司网站潍坊网站定制公司
  • 四川省住房和城乡建设厅新网站宜昌建设厅网站
  • 建设网站一般流程建设开发网站
  • 设计外贸英文网站国家企业信息信用公信系统
  • 主题资源网站创建时 如何突出设计的特点阿里云是做网站的吗
  • 乌市建设工程质量监督站网站外资公司注册
  • 档案馆网站机房建设做游戏网站打鱼
  • 网站建设平台 创新模式搭建好ftp服务器 如何通过网站访问
  • 苏州集团网站制作设计网页制作软件ai
  • 网站建设新手教程视频教程手帐风格wordpress主题
  • 做投标网站条件网站更改指定字段
  • mvc5 网站开发之美做印刷网站公司
  • 医疗网站建设精英微信网站用什么制作的
  • 银川网站设计联系电话地推加人2元1个
  • 龙华网站 建设深圳信科北京知名的网站建设公司
  • 怎么做qq刷赞网站搜盘 资源网
  • 微网站怎么做的好名字吗陕西省医院网站建设管理
  • 泉州seo-泉州网站建设公司温州企业自助建站系统
  • 网站建设属于什么费网站建设网络推广
  • 德州网站开发人员网站怎么才能被百度收录
  • wordpress网站怎么加小游戏乐山网站制作公司
  • 企业购 网站建设做兼职有哪些网站
  • 湖州网站做等保费用大型网站建站
  • 优创智汇高端网站建设网站设计工作流程
  • 什么网站可以学做西餐个人网站怎么做支付功能
  • 千户微建站平台做网站需要切图吗
  • 织梦cms 学校网站模板网站建设中的问题
  • 山东济南网站建设公司制作wordpress模板教程视频教程