针对将JSON数据和子对象转换为MSSQL中的行和将json对象转换成字符串这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Clang代码覆盖率没有正确覆盖#ifdef中的行、CSS中的行、
针对将 JSON 数据和子对象转换为 MSSQL 中的行和将json对象转换成字符串这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Clang 代码覆盖率没有正确覆盖 #ifdef 中的行、CSS 中的行、Jooq-将字段更新为NULL使其变为“ null”而不是NULL JSON.valueOf(null)与(JSON) null 使用Converter
- 将 JSON 数据和子对象转换为 MSSQL 中的行(将json对象转换成字符串)
- Clang 代码覆盖率没有正确覆盖 #ifdef 中的行
- CSS 中的行
- Jooq-将字段更新为NULL使其变为“ null”而不是NULL JSON.valueOf(null)与(JSON) null 使用Converter
converter = Converter.ofNullable( JSON.class, String.class, JSON::data, JSON::json ); 的注意事项 - json模块:json.dumps()、json.loads()、json.dump()、json.load()
将 JSON 数据和子对象转换为 MSSQL 中的行(将json对象转换成字符串)
如何解决将 JSON 数据和子对象转换为 MSSQL 中的行
我在使用本网站进行学习后的第一个问题!仍然是初学者,所以对我放轻松:)
我正在尝试在 MSsql Server 中格式化 JSON 数据。我有一个静态 JSON 文件,我可以通过 OPENROWSET 显示它,并填充一个变量。这个 JSON 文件有一个“标题”,然后是一个或多个“子”行,基本上是一个订单标题和订单详细信息行。我可以成功地将标题的列单独显示为结果集中的表格。我只想对细节行做同样的事情 - 目的是然后将标题存储在一个表中,并将它的详细信息存储在 sql Server 中的一个表中 - 这部分我不会有问题。
这是我正在使用的一些模型 JSON 数据。这是我需要使用的确切格式,所以我没有任何操作空间,但我已经用测试数据填充了它:
{
"InputParameters" : {
"P_IN_ORDER_SOURCE" : "The_Web","P_IN_ORIG_SYS_DOCUMENT_REF" : "Order666","P_IN_SOLD_TO_CUST_NUMBER" : "JOEB11","P_IN_CUST_ORDER_NUMBER" : "JoeB5556667","P_IN_REQUEST_DATE" : "2021-01-20 08:10:06","P_IN_ORDER_ENTRY_DATE" : "2021-01-20 08:10:06","P_IN_SHIPTO_NAME" : "The Testing Co.","P_IN_SHIPTO_ADDR" : "82 Annweir Crescent","P_IN_SHIPTO_ADDR_2" : null,"P_IN_SHIPTO_CITY" : "Atlantis","P_IN_SHIPTO_STATE" : "WSX","P_IN_SHIPTO_ZIP" : "AT55 666","P_IN_SHIPTO_COUNTRY" : "GB","P_IN_OPERATION_CODE" : "CREATE","P_IN_BOOKED_FLAG" : "N","P_IN_OU_NAME" : "ATL UK OU","P_IN_SPECIAL_INSTRUCTIONS" : null,"P_IN_QUOTE_NUMBER" : null,"P_IN_PRICELIST_ID" : "8","P_IN_EMAIL" : "testemail@testemail.com","P_IN_SHIPTO_COUNTY" : null,"P_IN_SHIPPING_METHOD" : "Pre 930","P_IN_SHIPPING_INSTRUCTIONS" : null,"P_IN_ATTENTION_TO" : "Joe Bloggs","P_IN_FREIGHT_CARRIER_CODE" : null,"P_IN_IS_RETURN" : null,"P_IN_SALES_REP" : null,"P_IN_LINE_DATA" : [ {
"P_IN_LINE_DATA_ITEM" : [ {
"ORIG_SYS_DOCUMENT_REF" : "Order666","ORIG_SYS_LINE_REF" : "1","CUSTOMER_LINE_NUMBER" : "1","ITEM_TYPE_CODE" : "STANDARD","ITEM_DESCRIPTION" : "SKU7776","USER_ITEM_DESCRIPTION" : "SKU7776","TOP_MODEL_LINE_REF" : null,"LINK_TO_LINE_REF" : null,"COMPONENT_CODE" : null,"ORDERED_QUANTITY" : "6","ORDER_QUANTITY_UOM" : null,"UNIT_LIST_PRICE" : "16.95","UNIT_SELLING_PRICE" : "16.95","CALculaTE_PRICE_FLAG" : "N","OPERATION_CODE" : "INSERT"
},{
"ORIG_SYS_DOCUMENT_REF" : "Order666","ORIG_SYS_LINE_REF" : "2","CUSTOMER_LINE_NUMBER" : "2","ITEM_DESCRIPTION" : "SKU12345","USER_ITEM_DESCRIPTION" : "SKU12345","UNIT_LIST_PRICE" : "11.89","UNIT_SELLING_PRICE" : "11.89","ORIG_SYS_LINE_REF" : "3","CUSTOMER_LINE_NUMBER" : "3","ITEM_DESCRIPTION" : "SKU9999","USER_ITEM_DESCRIPTION" : "SKU9999","ORDERED_QUANTITY" : "8","UNIT_LIST_PRICE" : "46.42","UNIT_SELLING_PRICE" : "46.42","OPERATION_CODE" : "INSERT"
} ]
} ]
}
}
从今天开始,我一直在努力学习如何在 sql 服务器中使用这个 JSON。我已经探索了 OPEnjsON() 函数,就像我说的那样,我可以用标题信息定义单独的列和路径 - 但是一旦我尝试对详细信息对象执行类似和路径操作,我就会返回 NULL在每一列中。
有什么建议吗?如果我在这里遗漏了任何关键信息,我深表歉意!非常感谢!
解决方法
像这样:
declare @json nvarchar(max) = ''
{
"InputParameters" : {
"P_IN_ORDER_SOURCE" : "The_Web","P_IN_ORIG_SYS_DOCUMENT_REF" : "Order666","P_IN_SOLD_TO_CUST_NUMBER" : "JOEB11","P_IN_CUST_ORDER_NUMBER" : "JoeB5556667","P_IN_REQUEST_DATE" : "2021-01-20 08:10:06","P_IN_ORDER_ENTRY_DATE" : "2021-01-20 08:10:06","P_IN_SHIPTO_NAME" : "The Testing Co.","P_IN_SHIPTO_ADDR" : "82 Annweir Crescent","P_IN_SHIPTO_ADDR_2" : null,"P_IN_SHIPTO_CITY" : "Atlantis","P_IN_SHIPTO_STATE" : "WSX","P_IN_SHIPTO_ZIP" : "AT55 666","P_IN_SHIPTO_COUNTRY" : "GB","P_IN_OPERATION_CODE" : "CREATE","P_IN_BOOKED_FLAG" : "N","P_IN_OU_NAME" : "ATL UK OU","P_IN_SPECIAL_INSTRUCTIONS" : null,"P_IN_QUOTE_NUMBER" : null,"P_IN_PRICELIST_ID" : "8","P_IN_EMAIL" : "testemail@testemail.com","P_IN_SHIPTO_COUNTY" : null,"P_IN_SHIPPING_METHOD" : "Pre 930","P_IN_SHIPPING_INSTRUCTIONS" : null,"P_IN_ATTENTION_TO" : "Joe Bloggs","P_IN_FREIGHT_CARRIER_CODE" : null,"P_IN_IS_RETURN" : null,"P_IN_SALES_REP" : null,"P_IN_LINE_DATA" : [ {
"P_IN_LINE_DATA_ITEM" : [ {
"ORIG_SYS_DOCUMENT_REF" : "Order666","ORIG_SYS_LINE_REF" : "1","CUSTOMER_LINE_NUMBER" : "1","ITEM_TYPE_CODE" : "STANDARD","ITEM_DESCRIPTION" : "SKU7776","USER_ITEM_DESCRIPTION" : "SKU7776","TOP_MODEL_LINE_REF" : null,"LINK_TO_LINE_REF" : null,"COMPONENT_CODE" : null,"ORDERED_QUANTITY" : "6","ORDER_QUANTITY_UOM" : null,"UNIT_LIST_PRICE" : "16.95","UNIT_SELLING_PRICE" : "16.95","CALCULATE_PRICE_FLAG" : "N","OPERATION_CODE" : "INSERT"
},{
"ORIG_SYS_DOCUMENT_REF" : "Order666","ORIG_SYS_LINE_REF" : "2","CUSTOMER_LINE_NUMBER" : "2","ITEM_DESCRIPTION" : "SKU12345","USER_ITEM_DESCRIPTION" : "SKU12345","UNIT_LIST_PRICE" : "11.89","UNIT_SELLING_PRICE" : "11.89","ORIG_SYS_LINE_REF" : "3","CUSTOMER_LINE_NUMBER" : "3","ITEM_DESCRIPTION" : "SKU9999","USER_ITEM_DESCRIPTION" : "SKU9999","ORDERED_QUANTITY" : "8","UNIT_LIST_PRICE" : "46.42","UNIT_SELLING_PRICE" : "46.42","OPERATION_CODE" : "INSERT"
} ]
} ]
}
}
''
select *
from openjson(@json,''$.InputParameters.P_IN_LINE_DATA[0].P_IN_LINE_DATA_ITEM'')
with
(
ORIG_SYS_DOCUMENT_REF varchar(200),ORIG_SYS_LINE_REF int,CUSTOMER_LINE_NUMBER int,ITEM_TYPE_CODE varchar(200),-- . . .
OPERATION_CODE varchar(200)
)
Clang 代码覆盖率没有正确覆盖 #ifdef 中的行
如何解决Clang 代码覆盖率没有正确覆盖 #ifdef 中的行
我有这个版本的叮当声:
clang version 10.0.0
Target: x86_64-unkNown-linux-gnu
Thread model: posix
我尝试为这个 test.cpp
生成覆盖率:
#define DEBUG 0
#include <iostream>
int main() {
#if DEBUG
std::cout << "IN DEBUG\\n";
#else
std::cout << "IN norMAL\\n";
#endif
return 0;
}
使用命令:
$ clang++ -fprofile-instr-generate=test.profraw -fcoverage-mapping test.cpp -o test
$ llvm-profdata merge -sparse -instr test.profraw -o test.profdata
$ llvm-cov show ./test -instr-profile=test.profdata
这是输出:
1| |#define DEBUG 0
2| |#include <iostream>
3| 1|int main() {
4| |#if DEBUG
5| | std::cout << "IN DEBUG\\n";
6| |#else
7| | std::cout << "IN norMAL\\n";
8| 1|#endif
9| 1| return 0;
10| 1|}
11| |
这看起来是不是有问题?此处应涵盖第 7 行。我知道它弄乱了编译器指令,但我认为 clang 应该足够聪明来解决这个问题。有人对如何解决此问题有任何建议吗?
CSS 中的行
哪里说起呢?就从一道老生常谈的前端面试题开始吧。
块级元素与行内元素
问:块级元素和行内元素有什么区别?
估计各位同学都在各种前端面试中被问到过,当然也在各种网站上搜寻过答案。要真正罗列两者的区别可以找到很多,然而从本质上讲,就是这样的区别:
- 块级(
block
)元素可以控制它的大小 - 行内(
inline
)元素将其排到父级的行系统中
我更愿意把这两者称作为元素的两个特性。因为行内元素具有 inline
特性,所以多个行内元素会排在一行;但它们不具有 block
特性,所以无法使用 width
、height
指定它们的宽高。因为块级元素具有 block
特性,所以可以直接指定元素的宽高;因为块级元素不具有 inline
特性,所以它们会独占一行。
这两个特性还可以叠加:同时具有 inline
和 block
特性的就是行内块(inline-block
)元素,既可以设定宽高,也会排到行系统中。如果两个特性都不具备,那么就是 display: none
。
注意这里所说的 block
和 inline
都是相对于同级元素而言的,对于元素的子级又有不同的布局方式。如果指定不同子节点的布局方式与 block
、inline
特性叠加,又有了 table
(具有 block
特性、子元素使用 table
方式布局)、inline-table
(具有 inline
、block
特性,子元素使用 table
方式布局),flex
、inline-flex
,grid
、inline-grid
等等。
有了这样的概念,就可以解释一些特殊的现象。比如 text-align
对块级元素不起作用:因为块级元素所在的行独立于父级行系统之外,一个设置行内位置排布的 CSS 属性当然不会起作用。再比如 margin: 0 auto
只对块级元素起作用:因为只有块级元素独占一行,它才有充足的空间自由的在行中排布。
请再次注意:text-align
排的是元素的子节点,而 margin
排的是元素本身。
HTML 页面默认采用流式布局,水平方向和竖直方向是不对等的。在默认情况下,HTML 页面中的文字总是会按书写顺序(writing-mode
)横着从左往右排,一行占满之后会在这行的下面另起一行。text-align
不是不能对竖直方向其作用,只需要当前的行系统是竖排的(writing-mode: vertical-lr
)。margin: auto 0
默认情况下不会将一个块级元素竖直居中,因为缺少 inline
特性只是让元素独占一行,而不会让他独占一列。
想让水平方向和竖直方向对等也很简单:position: absolute
,如果再使用 top: 0; bottom 0;
将元素竖直占满一列,就可以使用 margin: auto 0
将元素竖直居中。
行系统
那块级元素和表格元素有什么区别?区别是:块级(block
)元素使用行系统布局子节点。
所谓行系统就是基于行的子节点排布方式,默认情况下从左往右依次排列,超出一行时就折行。每个块级元素都有自己的行系统,block
元素如此,inline-block
元素也如此。不同的块级元素的行系统各自独立,就算它们有父子关系。你完全可以把某个块元素左对齐,然后把其子级的行内块元素右对齐,没有任何问题。
既然有了行的概念,那么每行占多高呢?这就有了行高的概念,由 CSS 属性 line-height
控制,默认值为 normal
,不同的浏览器对 normal
的处理不一致,你也可以手工指定其值。可以是一个数字,表示当前元素的 font-size
的倍数,也可以是一个绝对值,多少像素等。
元素的行高可以很大,也可以很小,也许放下行中的元素后上下还有空余,也许刚刚好,也许根本放不下。控制行中节点位置的 CSS 属性是 vertical-align
,默认是 baseline
。
行中最常存放的节点是文本。由于各个字符的高度各不相同,为了显示的整齐,不能通过简单的对齐上下两边或中心排列行中的字符。每个字符都需要有一个基准去做对齐,这样就有了基线(baseline
)的概念。
可以看到图片中的后几个字母 hinx
下边都有一两个短横,它们叫做衬线,带有衬线的字体叫做衬线字体。它们在同一条直线上,这条直线所在的位置就是基线。文本默认按照基线对齐,基线的位置跟当前字体有关,不同的字体位置不同。当行高超出最大字符高度时,基线会往行中间移动,这就是为什么把 line-height
的值设置为父元素高度时可以将文本竖直居中的原因。
vertical-align
还有几个可选值,其中最常用的应该是 middle
了。各位同学应该遇到过这样的问题:给一个内联块元素设置了 vertical-align: middle
,但这个元素并非在正中,总会偏离一点点。vertical-align: middle
其实并不是把元素绝对的居于父元素中间(不要看 w3school 等上面的初学者向文档),MDN) 上给的官方说明为:
元素中垂线与父元素的基线加上小写x一半的高度值对齐。
vertical-align: middle
的对齐方式与父元素的基线和字号有关,然而这个值未必就是父元素的中线。那么解决的方法也很简单,设置父元素 font-size: 0
,字号为 0 时基线必然在元素正中,这个 小写x一半的高度值
也必然是 0。
额对了,font-size: 0
还有一个用处是干掉多余的空格,这在使用 display: inline-block
做横向布局时非常有用。
再次注意 vertical-align
控制的是内联元素在其所在行的行内居中,它只对带有 inline
特性的元素起作用,包括内联块元素。另外如果你用 vertical-align: middle
使某元素竖直居中于父元素中间,记得同时设置 white-space: nowrap
,防止多个元素折行。
前面提到了 text-align
,除了常用的 left
、center
、right
取值以外,还有一个很有用的取值:justify
——两端对齐。在只有一行时,两端对齐就相当于左对齐;但是有多行时,两端对齐会将除最后一行外的前面所有行按单词(空白字符)拆分均匀分散对齐。其实这个值对于行中的内联块元素同样有效。
为了使 text-align: justify
生效,你必须保证有多行(只对最后一行之前的行生效),必须保证相邻内联块元素中间有空白字符(并且字号不能为 0)。前者可以通过一个 display:inline-block; width: 100%
的伪元素实现(伪元素作最后一行);后者如果是手写的 HTML 基本一般通常都会有,如果是用 ng-repeat
、v-for
生成的元素就要非一些力气手工制造出来。
text-align: justify
这个相对 hack 的用法有很高的浏览器兼容性,需要兼容 IE8 的同学或多或少应该都有使用过,可能也遇到过各种各样的问题。后来的伸缩盒(flex
)布局中有更加好用的 justify-content: space-between
是此属性的绝佳替代品,这是后话。
还有一些 CSS 属性控制行系统的布局方式。除了前面的提到的 text-align
和 white-space
,还有 word-wrap
(控制折行时是否允许拆分单词)、text-overflow
(控制超出一行时的处理方式)等等。除此之外,常用的 margin
、padding
对于行内元素的效果也有不同之处,留给各位同学自己发现。
Jooq-将字段更新为NULL使其变为“ null”而不是NULL JSON.valueOf(null)与(JSON) null 使用Converter converter = Converter.ofNullable( JSON.class, String.class, JSON::data, JSON::json ); 的注意事项
如何解决Jooq-将字段更新为NULL使其变为“ null”而不是NULL JSON.valueOf(null)与(JSON) null 使用Converter<JSON, String> converter = Converter.ofNullable( JSON.class, String.class, JSON::data, JSON::json ); 的注意事项
所以这是我以前在jooq 3.11中使用的查询。
我正在更新JSON字段,但是使用JsonBinding将其映射到模型中的String,我将在其下方发布
dsl.update(TASK)
.set(TASK.JSON_SOLUTION,(String) null).
.where(TASK.TENANT.eq(getCurrentTenant()))
.and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()
现在升级到jooq 3.13.2后,该功能不再起作用。即使我正在使用MysqL 5_7数据库,我也不得不将sql方言更改为MysqL,这可能是问题所在?
我也尝试过,但还是一样
dsl.update(TASK)
.setNull(TASK.JSON_SOLUTION).
.where(TASK.TENANT.eq(getCurrentTenant()))
.and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()
JsonBinding.class
public class JsonBinding implements Binding<JSON,String> {
@Override
public Converter<JSON,String> converter() {
return new JsonConverter();
}
@Override
public void sql(BindingsqlContext<String> bindingsqlContext) {
if (bindingsqlContext.render().paramType() == ParamType.INLINED) {
bindingsqlContext
.render()
.visit(DSL.inline(bindingsqlContext.convert(converter()).value()))
.sql("::json");
} else {
bindingsqlContext.render().sql("?");
}
}
@Override
public void register(BindingRegisterContext<String> bindingRegisterContext) throws sqlException {
bindingRegisterContext
.statement()
.registerOutParameter(bindingRegisterContext.index(),Types.VARCHAR);
}
@Override
public void set(BindingSetStatementContext<String> bindingSetStatementContext)
throws sqlException {
bindingSetStatementContext
.statement()
.setString(
bindingSetStatementContext.index(),Objects.toString(bindingSetStatementContext.convert(converter()).value(),null));
}
@Override
public void set(BindingSetsqlOutputContext<String> bindingSetsqlOutputContext)
throws sqlException {
throw new sqlFeatureNotSupportedException();
}
@Override
public void get(BindingGetResultSetContext<String> bindingGetResultSetContext)
throws sqlException {
bindingGetResultSetContext
.convert(converter())
.value(
JSON.valueOf(
bindingGetResultSetContext
.resultSet()
.getString(bindingGetResultSetContext.index())));
}
@Override
public void get(BindingGetStatementContext<String> bindingGetStatementContext)
throws sqlException {
bindingGetStatementContext
.convert(converter())
.value(
JSON.valueOf(
bindingGetStatementContext
.statement()
.getString(bindingGetStatementContext.index())));
}
@Override
public void get(BindingGetsqlInputContext<String> bindingGetsqlInputContext) throws sqlException {
throw new sqlFeatureNotSupportedException();
}
}
JsonConverter.class
public class JsonConverter implements Converter<JSON,String> {
@Override
public String from(JSON object) {
return object != null ? object.toString() : null;
}
@Override
public JSON to(String string) {
return JSON.valueOf(string);
}
@Override
public Class<JSON> fromType() {
return JSON.class;
}
@Override
public Class<String> toType() {
return String.class;
}
}
这是jooq使用.setNull()运行的查询
update `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = ''null''::json where (`tasks_service`.`task`.`tenant` = ''skynet'' and `tasks_service`.`task`.`task_template_id` in (''55'',''33''))
在jooq 3.11升级之前,查询是这样
update `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = null::json where (`tasks_service`.`task`.`tenant` = ''skynet'' and `tasks_service`.`task`.`task_template_id` in (''55'',''33''))
因此,在将其设置为''json_solution''= null之前,以及在升级之后,似乎将其设置为''json_solution''=''null''
不太确定为什么会这样吗?
编辑:因此,据我所知,这似乎完全来自于JOOQ的升级,而不是sql-dialect。如果同时将Jooq 3.11.5与MysqL和MysqL_5_7用作方言,则将查询构建为set''json_solution''= null,如果我将JOOQ升级到3.13.2,则将其set''json_solution''=''null''
这个怪癖似乎也只发生在JSON字段上,我尝试将同一表上的另一个varchar String字段设置为null,然后得到正确的设置“ field_name''= null
问题可能出在我的JsonBinding / JsonConverter吗?我必须对其稍作修改,以便与JOOQ中的新JSON对象一起使用,因为以前的JOOQ将JSON映射为Object
解决方法
JSON.valueOf(null)
与(JSON) null
答案在org.jooq.JSON
的Javadoc中:
CAST(NULL AS JSON)
值由类型为null
的{{1}}引用而不是JSON
表示。这与jOOQ从data() == null
和NULL
方法返回Result
的一般方法是一致的。
因此,错误在于Record
使用JSON.valueOf()
。改写成这样:
JsonConverter
或者,只需使用Converter.ofNullable()
,它即可为您处理空对空映射:
public JSON to(String string) {
return string == null ? null : JSON.valueOf(string);
}
使用Converter<JSON,String> converter = Converter.ofNullable( JSON.class,String.class,JSON::data,JSON::json );
的注意事项
由于jOOQ本机支持Binding
类型,因此您实际上不再需要绑定。如果您要将JSON
转换为JSON
,则您的String
就足够了。
json模块:json.dumps()、json.loads()、json.dump()、json.load()
json.dumps()、json.loads()、json.dump()、json.load() 4个方法的总结和使用:
注意:存在文件里面的东西,读出来都是字符串
import json
1、json.dumps()使用
2、json.loads()使用
3、json.load()的使用
4、json.dump()的使用
今天的关于将 JSON 数据和子对象转换为 MSSQL 中的行和将json对象转换成字符串的分享已经结束,谢谢您的关注,如果想了解更多关于Clang 代码覆盖率没有正确覆盖 #ifdef 中的行、CSS 中的行、Jooq-将字段更新为NULL使其变为“ null”而不是NULL JSON.valueOf(null)与(JSON) null 使用Converter
本文标签: