I have a Oracle database where one of the column are XMLTYPE.
When I run the query in console it gives me back the column and the xml content.
SELECT DATA_RECEIVED
FROM schema.taxCard
WHERE FNR = (?) AND result = 'taxCardOK'
This is working fine. But in Kotlin code I get the following error:
java.sql.SQLException: Invalid column type
at oracle.jdbc.driver.NamedTypeAccessor.getSQLXML(NamedTypeAccessor.java:438)
at oracle.jdbc.driver.OracleResultSetImpl.getSQLXML(OracleResultSetImpl.java:1251)
at com.zaxxer.hikari.pool.HikariProxyResultSet.getSQLXML(HikariProxyResultSet.java)
My code looks like this:
fun Connection.hentSkattekortPaFnr(
fnr: String
): String {
val statement = prepareStatement(
"""
SELECT DATA_RECEIVED
FROM schema.taxCard
WHERE FNR = (?) AND result = 'taxCardOK'
""".trimIndent()
).apply {
setString(1, fnr)
}
val resultSet = statement.executeQuery()
val xml = resultSet.asSequence { resultSet.getSQLXML(1) }.first()
return xml.string
}
fun <T> ResultSet.asSequence(extract: () -> T ) : Sequence<T> = generateSequence{
if (this.next()) extract() else null
}
What am I doing wrong?
Related
We have worked on this code to error trap a value entered in a Edit Text field
When the value is entered correctly we are informed that the entered value does not match
BUT if we select the value from a recycler view list and populate the Edit Text field with the value the search tells us we have a match
Here is the code for the search in the DBHelper
fun getOneName(id: Int): Contact? {
val db = this.writableDatabase
val selectQuery = "SELECT * FROM $TABLE_NAME WHERE $colId = ?"
db.rawQuery(selectQuery, arrayOf(id.toString())).use { // .use requires API 16
if (it.moveToFirst()) {
val result = Contact(id = 0,name ="")
result.id = it.getInt(it.getColumnIndex(colId))
result.name = it.getString(it.getColumnIndex(colName))
return result
}
}
return null
}
We used this for the Model Class our first time using data class as just plain class
data class Contact (
var id: Int,
var name: String
)
And here is the button click that manages the search
btnGetID.setOnClickListener {
if(etPerson.text.toString().trim().isNullOrEmpty()){
message("Enter Contact Name")
return#setOnClickListener
}
var numeric = true
var string = etPerson.text.toString().trim()
numeric = string.matches(".*\\d+.*".toRegex())
if(numeric){
message("No NUMBERS")
return#setOnClickListener
}
val dbManager = DBHelper(this)
var name = etPerson.text.toString()
//val contact = dbManager.getOneName(name)
val contact = dbManager.getOneName(id.toInt())
if(contact?.name.equals(name)){
println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! contact ID= "+contact)
etPerson.setText("The contact name is $name the ID is "+contact?.id.toString())
}else{
etPerson.setText("Name NOT = to $name and the ID is "+contact?.id.toString())
}
}
We know the name Sally is in the DB if we type Sally in the else statement shows Name NOT = bla
If we select Sally from the Recyclerview List the first statement shows The contact name bla bla
Kotlin 1.2.71 API 27
Our question is why is the hand typed name failing if it mataches?
HERE IS THE CORRECT CODE FOR THE DBHelper
fun getOneName(name: String): Contact? {
val db = this.writableDatabase
val selectQuery = "SELECT * FROM $TABLE_NAME WHERE $colName = ?"
db.rawQuery(selectQuery, arrayOf(name)).use { // .use requires API 16
if (it.moveToFirst()) {
val result = Contact(id = 0,name ="")
result.id = it.getInt(it.getColumnIndex(colId))
result.name = it.getString(it.getColumnIndex(colName))
return result
}
}
return null
}
I want to retrieve all determined columns from the model table as queryable
I write code blow it shows me
Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
any help to solve this error with the best practice:**
public IQueryable<DAL.model> GetAllmodels()
{
var models = (from d in db.models
where (d.Model_Deleted == false)
select (
new
{
d.Model_ID,
d.Model_Name,
d.Model_Image
})).AsQueryable();
return models;
}
Instead of selecting anonymous object with new { .. } Try as below with new DAL.model() { ... }.
public IQueryable<DAL.model> GetAllmodels()
{
var models = (from d in db.models
where (d.Model_Deleted == false)
select (
new DAL.model()
{
Model_ID = d.Model_ID,
Model_Name = d.Model_Name,
Model_Image = d.Model_Image
})).AsQueryable();
return models;
}
i have done of code that it executes any query in scala it works perfect unless if my query has to use same parameter twice. the database version is 12 and the oracle jar is ojdbc6, i wrote this code in order to execute query
def executeQuery(locale: String, query: String, input: Map[String, String], output: List[String]): Vector[Map[String, Any]] = {
var connection: Connection = null;
val properties = ConnectionLoader.getConnectionProperties(locale);
try {
connection = getDBConnection(properties);
val statement = connection prepareCall (query)
if (null != input)
for ((k, v) <- input) {
statement.setObject(k, v)
}
for (k <- output) {
statement.registerOutParameter(k, OracleTypes.INTEGER)
}
val resultSet = statement.executeQuery();
realize(resultSet);
} catch {
case e => throw e;
} finally {
if (null != connection)
connection.close();
}
}
and my query is
SELECT COUNT (1)
FROM ORDERS
WHERE ORDER_ID = :P_ORDER_ID AND STATUS_ID = 4
this query works fine but im getting an error when executing
SELECT COUNT (1)
FROM ORDERS
WHERE ORDER_ID = :P_ORDER_ID AND STATUS_ID = 4 and :P_ORDER_ID=9
Regardless to this unlogical query i'm getting this error
Execution exception[[SQLException: Missing IN or OUT parameter at index:: 2]]
i have googled everything but i got no result please advise
We have a table with a CLOB column (to save JSON data)
As we understand (from the docs) slick support LOB types (http://slick.lightbend.com/doc/3.1.1/schemas.html)
We are able to query the table succesfuly. Including the CLOB column.
We are not able to insert a register with a Clob. We are converting a String to java.sql.Clob with:
private java.sql.Clob stringToClob(String source)
{
try
{
return new javax.sql.rowset.serial.SerialClob(source.toCharArray());
}
catch (Exception e)
{
log.error("Could not convert string to a CLOB",e);
return null;
}
}
but in the end the exception from slick is the following:
java.lang.ClassCastException: javax.sql.rowset.serial.SerialClob cannot be cast to oracle.sql.CLOB
Is this possible?
We finally found a workaround as follows:
According to the column definition in slick
def column[C](n: String, options: ColumnOption[C]*)(implicit tt: TypedType[C]): Rep[C]
You can specify how the column is going to be translated between the driver and your code. If you want to use the out-of-the-box translations fine but for Oracle the translation for the CLOB type doesn't seem to work properly.
What we did was to define the column as a String but letting Slick to handle the translation with our custom code. The column definiton is the following:
def myClobColumn = column[String]( "CLOBCOLUMN" )( new StringJdbcType )
asd
Being StringJdbcType our custom code to solve the translation between our String to be inserted (up to 65535 bytes) and an Oracle CLOB.
The code for StringJdbcType is as follows:
class StringJdbcType extends driver.DriverJdbcType[String] {
def sqlType = java.sql.Types.VARCHAR
// Here's the solution
def setValue( v: String, p: PreparedStatement, idx: Int ) = {
val conn = p.getConnection
val clob = conn.createClob()
clob.setString( 1, v )
p.setClob( idx, clob )
}
def getValue( r: ResultSet, idx: Int ) = scala.io.Source.fromInputStream( r.getAsciiStream( "DSPOLIZARIESGO" ) )( Codec.ISO8859 ).getLines().mkString
def updateValue( v: String, r: ResultSet, idx: Int ) = r.updateString( idx, v )
override def hasLiteralForm = false
}
The setValue function was our salvation because we could build an Oracle CLOB with the already instantiated PreparedStatement and the String comming from our domain. In our implementation we only had to do the plumbing and dirty work for the Oracle CLOB.
In sum, the extension point offered by Slick in driver.DriverJdbcType[A] was what we actually used to make the thing work.
These are some improvements related to the solution: close resources and stream inspection
class BigStringJdbcType
extends profile.DriverJdbcType[String] {
def sqlType: Int = java.sql.Types.VARCHAR
def setValue(v: String, p: PreparedStatement, idx: Int): Unit = {
val connection = p.getConnection
val clob = connection.createClob()
try {
clob.setString(1, v)
p.setClob(idx, clob)
} finally {
clob.free()
}
}
def getValue(r: ResultSet, idx: Int): String = {
val asciiStream = r.getAsciiStream(idx)
try {
val (bufferEmpty, encoding) = getInputStreamStatus(asciiStream)
if (bufferEmpty) {
convertInputStreamToString(asciiStream, encoding)
} else ""
} finally {
asciiStream.close()
}
}
def updateValue(v: String, r: ResultSet, idx: Int): Unit =
r.updateString(idx, v)
override def hasLiteralForm: Boolean = false
}
Some utilities to complement the solution
def getInputStreamStatus(stream: InputStream): (Boolean, String) = {
val reader = new InputStreamReader(stream)
try {
val bufferEmpty = reader.ready()
val encoding = reader.getEncoding
bufferEmpty -> encoding
} finally {
reader.close()
}
}
def convertInputStreamToString(
stream: InputStream,
encoding: String
): String = {
scala.io.Source.fromInputStream(stream)(encoding).getLines().mkString
}
I tried to use JDBC driver of Apache Drill programatically.
Here's the code:
import java.sql.DriverManager
object SearchHbaseWithHbase {
def main(args: Array[String]): Unit = {
Class.forName("org.apache.drill.jdbc.Driver")
val zkIp = "192.168.3.2:2181"
val connection = DriverManager.getConnection(s"jdbc:drill:zk=${zkIp};schema:hbase")
connection.setSchema("hbase")
println(connection.getSchema)
val st = connection.createStatement()
val rs = st.executeQuery("SELECT * FROM Label")
while (rs.next()){
println(rs.getString(1))
}
}
}
I have set the database schema with type : hbase, Like:
connection.setSchema("hbase")
But it fails with the error code:
Exception in thread "main" java.sql.SQLException: VALIDATION ERROR:
From line 1, column 15 to line 1, column 19: Table 'Label' not found
SQL Query null
The Label table is exactly exit in my hbase.
I can find My data when I use sqline like:
sqline -u jdbc:drill:zk....
use hbase;
input :select * from Label;
I have solved this problem. I confused the drill's schema and jdbc driver schema......
the correct codes should be like:
object SearchHbaseWithHbase{
def main(args: Array[String]): Unit = {
Class.forName("org.apache.drill.jdbc.Driver")
val zkIp = "192.168.3.2:2181"
val p = new java.util.Properties
p.setProperty("schema","hbase")
// val connectionInfo = new ConnectionInfo
val url = s"jdbc:drill:zk=${zkIp}"
val connection = DriverManager.getConnection(url, p)
// connection.setSchema("hbase")
// println(connection.getSchema)
val st = connection.createStatement()
val rs = st.executeQuery("SELECT * FROM Label")
while (rs.next()){
println(rs.getString(1))
}
}
}