我正在查詢Postgres中的表以查看是否存在具有主鍵值的行匹配給定Map
中的行。如果沒有結果,我想插入一個新行。當我使用創建預準備語句的標準JDBC路由並明確設置所有列值時,我可以很好地做到這一點,但是我希望Groovy的Sql
類可以提供更通用的方法。向Postgres插入行時出現空指針異常
這是我的INSERT語句(主鍵列的前三個):
insert into MY_TABLE
(contract_month, contract_year, publish_date, open, high, low)
values
(10, 2015, 2015-09-15 00:00:00.0, 46.65, 46.9, 45.98)
的問題是,我是從Postgres的司機儘快得到一個NullPointerException
我插入一行:
Exception in thread "main" java.lang.NullPointerException
at org.postgresql.core.v3.SimpleParameterList.setNull(SimpleParameterList.java:142)
at org.postgresql.jdbc2.AbstractJdbc2Statement.setNull(AbstractJdbc2Statement.java:1259)
at org.postgresql.jdbc3.AbstractJdbc3Statement.setNull(AbstractJdbc3Statement.java:1499)
at org.postgresql.jdbc4.AbstractJdbc4Statement.setNull(AbstractJdbc4Statement.java:85)
at org.postgresql.jdbc2.AbstractJdbc2Statement.setObject(AbstractJdbc2Statement.java:2092)
at org.postgresql.jdbc3g.AbstractJdbc3gStatement.setObject(AbstractJdbc3gStatement.java:38)
at org.postgresql.jdbc4.AbstractJdbc4Statement.setObject(AbstractJdbc4Statement.java:48)
挖掘到它,我發現一個名爲ProtoConnection
的對象在org.postgresql.core.v3.SimpleParameterList
類中爲null。我究竟做錯了什麼?
這是包裹代碼創建對象Sql
:
private Main() {
final def headers = new HashMap<Integer, String>()
final def record = new HashMap<String, Object>()
Sql.withInstance(/* my db */) { final Sql sql ->
sql.withBatch {
new URL(/* my url */).withReader {
it.readLines().each {
if (headers.isEmpty()) {
setHeaders it, headers
}
else {
processRecord it, headers, record
storeRecord sql, record
}
}
}
}
}
}
而這是數據庫的邏輯。錯誤發生在最後一行:
def storeRecord = { final Sql sql, final Map<String, Object> record ->
final def connection = sql.connection
final def metadata = connection.metaData
final def columns = metadata.getColumns(null, null, MY_TABLE, null).with {
final def result = []
while (it.next()) {
result << it.getString(4)
}
result
}
final def primaryKeys = metadata.getPrimaryKeys(null, null, MY_TABLE).with {
final def result = []
while (it.next()) {
result << it.getString(4)
}
result
}
final def whereClause = primaryKeys.collect { final String pk ->
"$pk = ?.$pk"
}
final def select = """
select ${columns.join(', ')}
from MY_TABLE
where ${whereClause.join(' and ')}
"""
final def row = sql.firstRow(select, record)
if (row) {
println "Updating"
// Not implemented yet
}
else {
println "Inserting record: $record"
final def insert = """
insert into MY_TABLE
(${columns.findAll { null != record[it] }.join(", ")})
values
(${columns.findAll { null != record[it] }.collect { record[it] }.join(", ")})
"""
println insert
sql.executeInsert(insert, record)
}
你的堆棧跟蹤是不完整的,但我猜想,對於一個'NOT NULL」 fieldd在你的記錄圖的值爲空。 – hotzst
由於Groovy關閉的瘋狂,我縮寫了stacktrace。儘管存在所有非空列的值。 – lealand
感謝您的輸入,@hotzst。在經過幾次失敗後(主要在我身上)管理解決問題! – lealand