I am using org.apache.hadoop.hbase library to query hbase.
In h-base I have following:
table name : Employees
in this table I have following fields:
emp_id,name, age, designation, joining_date
how can I find designation of employee if I have his joining_date and name only.
I am using something like:
public static void getOneRecord (Configuration conf, String tableName, String rowKey, String rowKey2) throws IOException{
HTable table = new HTable(conf, tableName);
Get get = new Get(rowKey.getBytes());
Result rs = table.get(get);
for(KeyValue kv : rs.raw()){
System.out.print(new String(kv.getRow()) + " " );
System.out.print(new String(kv.getFamily()) + ":" );
System.out.print(new String(kv.getQualifier()) + " " );
System.out.print(kv.getTimestamp() + " " );
System.out.println(new String(kv.getValue()));
}
}
how can I extend it to 2 row keys.
Note: It is guaranteed that only one value will be returned by this pair query.
You want to get a record based on the columns which are not row keys. Please confirm this. If yes, following are the options
Good row key design for performance. If you would be querying more based on a column other than row key, you can consider looking at modifying row key design to append that column as part of row key. Then you can use get or scan with row key range, row filter or FuzzyRowFilter
Secondary index is one option.
Use filters(in your case two SingleColumnValueFilter) and add them as part of scan.here
Related
I would like to update multiple rows of a table using Case clause in the update query.
I have an Map<String, String> which contains values of 2 columns. Key acts as the identifier of the row and the value in the map is the value of the column I want to update.
How can I do this in a spring data JPA #Query?
I would like to achieve something like
#Modifying
#Query("update RequestDetail rd set value = VALUE(:statusDetails) where name='Status' and RequestUuid=KEY(:statusDetails)")
void updateBulkStatus(Map<String, String> statusDetails);
But this is giving the exception - antlr.SemanticException: node did not reference a map.
Goal is to avoid multiple update queries to DB.
What better ways we have to update multiple rows with multiple values to a single column.
You will need to execute something like:
Update RequestDetail rd set rd.value = CASE WHEN (rd.name = :name1) THEN :value1 WHEN (rd.name = :name2) THEN :value2 WHEN (rd.name = :name3) THEN :value3 END
But you will not necessarily know how many items will be in the map, so you will need to generate your query text, like
String sql = "Update RequestDetail rd set CASE ";
int index = 1;
for (Map.Entry<String,String> entry : statusDetails.entrySet()) {
sql += " WHEN (rd.name = :name" + index + ") THEN :value" + (index++) + " ";
}
sql += " END";
You will also need to pass the parameters to your query.
I wanted to make sure there were no duplicate timestamps in my table but then I found that it may be problematic if I simply use UNIQUE, because right now my table has:
_ID field (autoincrement)
Account ID (integer, links to an account table)
Category ID (integer, links to a category table)
Value (the value of this category for this account)
Timestamp (the timestamp of this value of this category for this account)
Is there a way to designate the timestamp field as unique within the context of the account ID and category ID? As in, it should not be possible to put in two values for a single timestamp, with respect to account and category. But the timestamp may show up multiple times in the table as a whole, either because it corresponds to other Categories and/or Accounts.
you can create a trigger and check whatever constraint you need:
#Override
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
database.execSQL("CREATE TRIGGER UNIQUE_TIMESTAMP_TRIGGER " +
"AFTER INSERT ON MY_TABLE FOR EACH ROW " +
"BEGIN " +
" SELECT RAISE(ABORT, 'Timestamp not unique') WHERE " +
" EXISTS(SELECT TIMESTAMP MY_TABLE T2 " +
" WHERE T2.TIMESTAMP = NEW.TIMESTAMP AND T2.ACCOUNT_ID = NEW.ACCOUNT_ID) " +
"END; ");
}
Using Java/Selenium/Excel sheets I have an automation script. When verifying information in the database, I am doing something like this:
//Get values from Excel. Excel user will specify what table and what user
String table=currentTestSuiteXLS.getCellData(currentTestCaseName, "table",currentTestDataSetID);
String user=currentTestSuiteXLS.getCellData(currentTestCaseName, "user",currentTestDataSetID);
//Run query
PreparedStatement pstmt1 = conn.prepareStatement("SELECT * FROM " + table +" WHERE User = '" + user + "' ORDER BY 1 DESC LIMIT 1;");
if(table.equals("A")){
rs1.next();
//Get results from A table
String db_TableAColumn1=rs1.getString("TableAColumn1");
String db_TableAColumn2=rs1.getString("TableAColumn2");
String db_TableAColumn3=rs1.getString("TableAColumn3");
//Get values from excel
String excel_TableAColumn1=currentTestSuiteXLS.getCellData(currentTestCaseName, "TableAColumn1",currentTestDataSetID);
String excel_TableAColumn2=currentTestSuiteXLS.getCellData(currentTestCaseName, "TableAColumn2",currentTestDataSetID);
String excel_TableAColumn3=currentTestSuiteXLS.getCellData(currentTestCaseName, "TableAColumn3",currentTestDataSetID);
if(db_TableAColumn1.equals(excel_TableAColumnA)) { ...
if(db_TableAColumn2.equals(excel_TableAColumn2)) { ...
if(db_TableAColumn3.equals(excel_TableAColumn3)) { ...
if(table.equals("B")){
rs1.next();
//Get results from B table
String db_TableBColumn1=rs1.getString("TableBColumn1");
String db_TableBColumn2=rs1.getString("TableBColumn2");
String db_TableBColumn3=rs1.getString("TableBColumn3");
//Get values from excel
String excel_TableBColumn1=currentTestSuiteXLS.getCellData(currentTestCaseName, "TableBColumn1",currentTestDataSetID);
String excel_TableBColumn2=currentTestSuiteXLS.getCellData(currentTestCaseName, "TableBColumn2",currentTestDataSetID);
String excel_TableBColumn3=currentTestSuiteXLS.getCellData(currentTestCaseName, "TableBColumn3",currentTestDataSetID);
if(db_TableBColumn1.equals(excel_TableBColumn1)) { ...
if(db_TableBColumn2.equals(excel_TableBColumn2)) { ...
if(db_TableBColumn3.equals(excel_TableBColumn3)) { ...
So this is currently working fine. However, it is not very scalable.
If we want to start to check a new column on the A table (or if a new column is added) we need to update the java code. We only want to modify the excel sheet. Is there a way to parse all the columns from the result set, and if a column is in the excel sheet then we check to see if it exists in the result set, if so, then check to see if the expected values match up?
Is there a way to do For each column in the table
String GiveAName= rs1.getString(1); until all columns are given a name
Then if each column in specified in excel has a value, match up.
Instead of defining everything like:
String db_TableAColumn1=rs1.getString("TableAColumn1");
or
String db_TableAColumn1= rs1.getString(1);
Thanks.
Use ResultSetMetaData http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html,
It will allow you to dynamically retrieve column names of a table.
example:
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
while (rs.next()){
for(int i=1; i<=columns; ++i){
System.out.println("Column name: " + md.getColumnName(i) + " Col Value: " +rs.getObject(i));
}
}
I have the following problem:
I have two tables in one data base which consist of the same columns besides the name of the last column. I want to write data into them using Java.
I want to use the same preparedStatement for both tables, where I check with an if-command whether it is table1 or table2. table2 has amount10 as the name for the last column, table1 has amount20 for it. This number is stored in a variable within my code.
Below you can see a (simplified) example and how I tried to let the column name variable but it doesn't work. Is there any way to fix this without copying the whole statement and manually changing the number variable?
String insertData = "INSERT INTO `database`.`"+table+"`
(`person_id`,`Date`,`amount`+"number") VALUES "+
"(?,?,?) ON DUPLICATE KEY UPDATE " +
"`person_id` = ? , " +
"`Date` = ? , " +
"`amount`+"number" = ? ; ";
PreparedStatement insertDataStmt;
This will not work since variables number and table are not going to be magically injected into your insertData string while you are changing them.
I'd to a method prepareInsertstatement(String table, String number) that would return correct PreparedStatement:
public void prepareInsertStatement(Connection conn, Strint table, String number) {
String insertData = "INSERT INTO `database`.`"+table+"`
(`person_id`,`Date`,`amount+"number"') VALUES "+
"(?,?,?) ON DUPLICATE KEY UPDATE " +
"`person_id` = ? , " +
"`Date` = ? , " +
"`amount+"number"' = ? ; ";
PreparedStatement insertDataStmt = conn.prepareStatement(insertData);
return insertDataStmt;
}
Just remember to close the PreparesStatement when you don't need it any more.
I suppose that reason for that is invalid syntax. When you concatenate string for last column name you use code 'amount' + number. If your number value is 20, than concat result will be
'amount'20 that cause invalid syntax exception. Just move one extra ' after number.
"'amount" + number + "'"
Note: log, or just error that appears during this statement execution would be very useful to find right answer for your question.
I have column family that have two primary keys
"CREATE TABLE compositkeys(user_name varchar," +
"user_id int,"+
"name varchar," +
"gender varchar," +
"PRIMARY KEY (user_name,user_id)" +
")";
I have created this in Java now i inserted 6 rows with on one user_name(sunil) primarykey with different id now when I try to retrieve all the value in sunil primary key it gives me only one detail
String qry = "select * from compositkeys where user_name = 'sunil' order by user_id";
Statement smt = con.createStatement();
//smt.executeUpdate(qry);
ResultSet rs = smt.executeQuery(qry);
//rs.get
int r = rs.getRow();
System.out.println(r);
ResultSetMetaData rm = rs.getMetaData();
int columnCount = rm.getColumnCount();
System.out.println(columnCount);
for(int i=1;i<=columnCount;i++)
{
String name = rm.getColumnName(i);
System.out.print(rm.getColumnName(i));
System.out.println(" = "+rs.getString(name));
System.out.println("--------------------------------------------------");
}
It gives me only one output. Is there any thing wrong in query? I want all the data under the key sunil.
You have a single loop that loops over the columns in a returned row, but you only ask for one row (that's the rs.getRow() method). You should put the rs.getRow() call and the following logic to write the results into an outer loop that iterates as long as getRow() doesn't return null. This out loop is what will retrieve all of a user's ids.