I am facing an issue with the SAS jdbc driver I have not seen before, and wondered what would be the correct JDBC behaviour.
Suppose I have some ResultSetMetaData:
metadata.getColumnName(index) -> col1
metadata.getColumnLabel(index) -> Column1
This would be the SQL result when running this query:
SELECT col1 AS Column1
When getting a value from a ResultSet, I expect to use this:
rs.getString("Column1")
But instead, I seem to have to use:
rs.getString("col1")
Is this to be expected and where my assumptions wrong? Or is this driver-specific behaviour?
In JDBC, you retrieve values of a result set by column label (the alias), not by column name. In the code in your question, the proper way to retrieve a value is using rs.getString("Column1") (or - as it is handled case-insensitive - rs.getString("COLUMN1"))
This is documented in the API, as all String based getters have the following documentation:
Parameters:
columnLabel - the label for the column specified with the SQL AS
clause. If the SQL AS clause was not specified, then the label is
the name of the column
Historically, JDBC 3 and earlier did not clearly discern between column labels and column names, which - to this day - results in drivers that require you to get by column name, or allow you to get both by column name or label, or return the column name from ResultSetMetaData.getColumnLabel(int) or the column label from ResultSetMetaData.getColumnName(int), or have configuration options to set which behavior to use.
Since you are using alias it seems the jdbc is expecting alias in that column name argument.
I found an related link for this : DB alias Resultset.
Hope this might be helpful
Related
I am trying to write java code to migrate data from oracle database to other database.
My use case is that different client have different version of code and so the database columns may vary. Clients with later version have additional column.
For eg : Client with new version as COL99 in the table SAMPLE_TABLE.
While writing the migration code, if I try to select the COL99 from SAMPLE_TABLE, it will work fine for the new client. But for clients on old version, the code fails with
ORA-00904 Invalid Identifier error.
Is there a way to handle in sql query or java code such that, if the column doesn't exist in the database table, simply ignore and do not return the value instead of throwing the exception.
You should first check, whether COL99 exists for your current database connection.
For Oracle you can use a query like this:
SELECT
COL.COLUMN_ID,
COL.OWNER AS SCHEMA_NAME,
COL.TABLE_NAME,
COL.COLUMN_NAME
FROM
SYS.ALL_TAB_COLUMNS COL
INNER JOIN
SYS.ALL_TABLES T
ON COL.OWNER = T.OWNER
AND
COL.TABLE_NAME = T.TABLE_NAME
WHERE
COL.OWNER = 'SCHEMA'
AND
COL.TABLE_NAME = 'SAMPLE_TABLE'
AND
COL.COLUMN_NAME = 'COL99'
Then you create your query with or without COL99.
I have a java Map (Map) and a JDBC connection to hive server.
The schema of the table at the server contains a column of type Map.
Is it possible to insert the java Map to the hive table column with similar datatype using JDBC?
I tried:
"create table test(key string, value Map<String, String>)"
"insert into table test values ('keywer', map('subkey', 'subvalue')) from dummy limit 1;"
ref: Hive inserting values to an array complex type column
but the insert failed with:
"Error: Error while compiling statement: FAILED: ParseException line 1:69 missing EOF at 'from' near ')' (state=42000,code=40000)"
[EDIT]
hive version is : 0.14.0
Thanks
The manual clearly says you cannot insert into a Map data type using SQL:
"Hive does not support literals for complex types (array, map, struct, union), so it is not possible to use them in INSERT INTO...VALUES clauses. This means that the user cannot insert data into a complex datatype column using the INSERT INTO...VALUES clause.”
I think the correct DDL and query would be:
CREATE TABLE test(key STRING, value MAP<STRING, STRING>);
INSERT INTO TABLE test VALUES('keywer', map('subkey', 'subvalue')) from dummy limit 1;
A working method to put a complex type from jdbc client is:
insert into table test select "key",map("key1","value1","key2","value2") from dummy limit 1;
where dummy is another table which has at least one row.
I try to query my Mysql DB using JDBC.
I use the org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations.
The column DATE_FROM in my_table is defined as DATE column (which is also a PK).
A simplified version of a query which works looks like this:
SELECT * FROM my_table WHERE DATE_FROM >='2015-03-01';
But then, I tried to change the the '2015-03-01' to be given as a named parameter. the query looked like this:
SELECT * FROM my_table WHERE DATE_FROM >=:fromDate;
while I invoked the NamedParameterJdbcOperations.update() like this:
map.put("fromTime", '2015-03-01');
namedParameterJdbcOperations.update(sql, map);
Although everything, to my understanding, remains the same, I get:
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect date value: ''2015-03-01'' for column 'MEASUREMENT_DATE' at row 1.
Does someone know why?
Did you realize that you named the placeholder in the SQL "fromDate" and in the map, you named it "fromTime"?
I am trying to build a query using jOOQ, this is my test code:
DSLContext create = DSL.using(SQLDialect.DERBY);
String query = create.select().from(TABLE).limit(1).offset(0).getSQL()
I get as query:
select field1, field2...fieldN etc from TABLE offset ? rows fetch next ? rows only
the problem is ? in ? rows fetch next ? rows only it seems to ignore the values that i used in limit and offset to build the query, why?
I am trying to select the first row from the results and I am using jooq 3.4.1
Thanks for the help
Query.getSQL() returns your SQL string with ? as placeholders for your bind variables. The idea is that you can feed this statement to a PreparedStatement and then explicitly bind all variables, which are available through Query.getBindValues().
You can also have jOOQ inline all your bind variables, by calling Query.getSQL(ParamType) as such:
String sql = query.getSQL(ParamType.INLINED);
I am using the following sql query in my java program:
SELECT COUNT(*) FROM event WHERE externaleventid ='1256294';
But I have an error as:
Invalid Column id.
Same query works fine in SQL Developer.
For some reason you are attempting to get a column named "externaleventid" from the query, but only "count(*)" is available. You shouldn't try to get back the where clause bind variables from the result set, you should get the actual data back from the result set, by column index or by column name.
Try rs.getInt(1) to get the data from the first column. Or, you can alias the column in the query, e.g. SELECT count(*) cnt FROM..., and you can refer to it by the aliased column name: rs.getInt("cnt").