Câu hỏi của tôi về cách viết truy vấn trong jooq dsl.
Tôi có một số danh sách thuộc tính máy khách được lưu trữ trong cơ sở dữ liệu Oracle.
Cấu trúc bảng như sau:
-
CLIENT_ATTRIBUTE_DICT
(ID, CODE, DEFAULT_VALUE) - Danh sách tất cả các thuộc tính có thể có
-
CLIENT_ATTRIBUTE
(ATTRIBUTE_ID, CLIENT_ID, VALUE) - Giá trị thuộc tính cho các client khác nhau
Tôi đang cố gắng chọn giá trị của tất cả các thuộc tính hiện có (trong từ điển) cho một khách hàng nhất định:
Nếu một hàng có clientId nhất định tồn tại trong CLIENT_ATTRIBUTE thì giá trị thuộc tính = CLIENT_ATTRIBUTE.VALUE
nếu không thìCLIENT_ATTRIBUTE_DICT.DEFAULT_VALUE
Truy vấn SQL của tôi (hoạt động tốt):
CHỌN d.code,
NVL
(
(
CHỌN giá trị
TỪ CLIENT_ATTRIBUTE một
Ở ĐÂU a.ATTRIBUTE_ID = d.id
VÀ a.CLIENT_ID = 1
),
(
CHỌN DEFAULT_VALUE
TỪ CLIENT_ATTRIBUTE_DICT đ
Ở ĐÂU dd.id=d.id
)
) giá trị
TỪ CLIENT_ATTRIBUTE_DICT d;
Truy vấn của tôi trong Jooq dsl:
ClientAttributionDictTable dict = CLIENT_ATTRIBUTE_DICT.as("d");
Thuộc tính bản đồ =
dsl.select(
dict.CODE,
DSL.nvl(
dsl.select(CLIENT_ATTRIBUTE.VALUE)
.from(CLIENT_ATTRIBUTE)
.Ở đâu(
CLIENT_ATTRIBUTE.ATTRIBUTE_ID.eq(dict.ID),
CLIENT_ATTRIBUTE.CLIENT_ID.eq(clientId)
),
dsl.select(CLIENT_ATTRIBUTE_DICT.DEFAULT_VALUE)
.from(CLIENT_ATTRIBUTE_DICT)
.where(CLIENT_ATTRIBUTE_DICT.ID.eq(dict.ID))
).as("giá trị")
).from(dict)
.fetchMap(String.class, String.class);
Khi truy vấn jooq được chạy, nó không thành công với thông báo lỗi:
Nguyên nhân: Loại lớp org.jooq.impl.SelectImpl không được hỗ trợ trong phương ngữ DEFAULT
tại org.jooq.impl.DefaultDataType.getDataType(DefaultDataType.java:757) ~[na:na]
tại org.jooq.impl.DefaultDataType.getDataType(DefaultDataType.java:704) ~[na:na]
tại org.jooq.impl.DSL.getDataType(DSL.java:14378) ~[na:na]
tại org.jooq.impl.DSL.val(DSL.java:12766) ~[na:na]
tại org.jooq.impl.Utils.field(Utils.java:802) ~[na:na]
tại org.jooq.impl.DSL.nvl(DSL.java:8403) ~[na:na]
我做错了什么?
CẬP NHẬTphiên bản JOOQ3.7.2
Có hai khía cạnh của lỗi này.
Việc sử dụng API của bạn hiện không được hỗ trợ (jOOQ hiện không chấp nhận nvl()
trong chức năng Select
kiểu). Thay vào đó hãy viết nó như thế này:
DSL.nvl(
DSL.field(dsl.select(CLIENT_ATTRIBUTE.VALUE)
// ^^ ^^^ ^^ ^^ bao bọc rõ ràng phần Chọn trong một trường
.from(CLIENT_ATTRIBUTE)
.Ở đâu(
CLIENT_ATTRIBUTE.ATTRIBUTE_ID.eq(dict.ID),
CLIENT_ATTRIBUTE.CLIENT_ID.eq(clientId))),
DSL.field(dsl.select(CLIENT_ATTRIBUTE_DICT.DEFAULT_VALUE)
// ^^ ^^^ ^^ ^^ bao bọc rõ ràng phần Chọn trong một trường
.from(CLIENT_ATTRIBUTE_DICT)
.where(CLIENT_ATTRIBUTE_DICT.ID.eq(dict.ID)))
).as("giá trị")
jOOQ (hay đúng hơn là trình biên dịch Java) không thể phát hiện việc lạm dụng API này vì nvl()
API bị quá tải nên nó luôn biên dịch. đây là vấn đềhttps://github.com/jOOQ/jOOQ/issues/5340và sẽ được sửa trong phiên bản tương lai (có thể là jOOQ 3.9)
Tôi là một lập trình viên xuất sắc, rất giỏi!