Is there a way to use ORDER BY and still use deleterow()? - sql

The code I'm using deletes the last row in the database. From what I have read, once I've used ORDER BY it will set the result back to read only which makes deleterow() or anything else involving updating the database not possible.
Is there a work around so I could make the table ORDER BY Score DESC and still delete the row I need to delete?
String host = "jdbc:derby://localhost:1527/Scores";
String uName = "root";
String uPass= "root";
Connection con = DriverManager.getConnection( host, uName, uPass );
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String SQLd = "select * from ROOT.HISCORES ORDER BY Score DESC";
ResultSet dl = stmt.executeQuery( SQLd );
dl.last();
dl.deleteRow();
}

This does not look like a good practice to me.
Instead of SELECTing data into Java and deleting it from there, just do it at the database level. Do a delete-select and skip most of the Java work.
Something like:
DELETE FROM root.hiscores
WHERE Score = (SELECT MIN(hs.Score) FROM root.hiscores hs)

Related

How to Safe input order by with SQLCommand in VbNet using SQLServer

Select cod,nom from tb_user where cod > #param0 order by #param1
Dim mycod = 3
Dim myorderby = "asc"
Dim _adapter = New SqlDataAdapter
cmd.CommandTimeout = timeout
cmd.Connection = _conn
cmd.CommandText = pSql
cmd.CommandType = CommandType.Text
Dim sqlParameter0 = New SqlParameter("#param0", mycod)
cmd.Parameters.Add(sqlParameter0)
Dim sqlParameter1 = New SqlParameter("#param1", myorderby)
cmd.Parameters.Add(sqlParameter1)
_adapter.SelectCommand = cmd
_adapter.Fill(_ds, "result")
I know I must replace the #param0 by the value of my variable mycod to be safe.
This is possible in the variables like the param0, but the #param1 where I put asc it gives me the following error:
the SELECT item identified by the ORDER BY number 1 contains a variable as part of the expression identitying a column position
PS: By the error it is clear the SqlParameter is not the way to input this kind of order by. Is there a way to input this kind of query safely?
You can do this by selectively ordering on the two columns.
Select cod,nom from tb_user
where cod > #param0
order by
case when #param1=1 then cod else 0 end,
case when #param1=2 then nom else 0 end
There are techniques to dynamically sort by a parameter but this can often lead to a significant slow down. I had a nightmare situation when I tried something similar.
The query worked well most of the time, but the query plan created was completely inappropriate when using a different parameter value, and the results took forever to return..
Since you're binding to a DataSet, you should just sort on the DefaultView after you call Fill().
_ds.Tables(0).DefaultView.Sort = myorderby

Empty result on native SQL query on Hibernate

I am trying to develop a simple method to execute sql queries on my application so I can use native sql for certain things.
This is the method I have:
Session session = getReportCsvMgr().getHibernateSession();
session.beginTransaction();
String sql = String.format("select USER_ID from Users where accountid = 'testaaa'");
Object o = session.createSQLQuery(sql).list();
System.out.println(o.toString());
session.close();
I do not get any errors but somehow the object o is empty and the sysout just prints [].
I debugged and the session works. I tested changing the name of the table and indeed it said "table does not exist". I also tried with and update statement, no errors but it does nothing.
Can anybody tell me what I need to do?
Thanks!
Change the line
Object o = session.createSQLQuery(sql).list();
to:
List<Integer> o = session.createSQLQuery(sql).list();
it the USER_ID is integer or to:
List<String> o = session.createSQLQuery(sql).list();
if the USER_ID is string.
Moreover in a query you have not passed params so you can change:
String sql = String.format("select USER_ID from Users where accountid = 'testaaa'");
to simple:
String sql = "select USER_ID from Users where accountid = 'testaaa'";
Either use .uniqueResult() instead of .list() if it only returns one row or change the return type to List<Object[]>

Query to retrieve all row data for supplied column name

I am using Eclipse and Oracle SQL Developer. My connections are all set up. I am trying to query my database in SQL Developer by passing in a column name as a variable.
For example, I just want to use something similar to this statement:
select * from CUSTOMERS;
but allow CUSTOMERS to be a variable where I can pass in any table name.
Currently this pulls all column names from given column name and connection:
final String query = "select column_name from all_tab_columns"
+" where owner = ?"
+" and table_name = ?";
try {
headers = DAO.useJNDI(jndi)
.setSQL(query)
.input(1, host)
.input(2, tableName)
.list(String.class);
I want to do the same thing but with rows. Does anyone know how to do this? This is what I am thinking about so far:
final String sql = "select *"
+ " from table_name"
+ " where owner = ? and table_name = ?";
try {
logger.debug(tableName+sourceJNDI);
sourceList = DAO.useJNDI(sourceJNDI)
.setSQL(sql)
.input(1, host)
.input(2, tableName)
.list(DatabaseCompareDto.class);
The main focus is the SQL statements. I know everything else works.
If I'm reading your question correctly, I think what you want is to replace the first table_name in your SQL with ?, then add an additional .input( 1, tableName) :
final String sql = "select *"
+ " from ?"
+ " where owner = ? and table_name = ?";
try {
logger.debug(tableName+sourceJNDI);
sourceList = DAO.useJNDI(sourceJNDI)
.setSQL(sql)
.input(1, tableName)
.input(2, host)
.input(3, tableName)
.list(DatabaseCompareDto.class);
You can't pass the table name as a parameter. Instead of wasting your energy on such an alleged generic solution, use or create a small templating engine which allows you to replace the table name in your query before sending it to the database.

Value copy function batch processing

I'm trying to copy values from one ID to another ID.
The ID and the timestamp are primary keys.
String sqlString = "SELECT * FROM Values WHERE ID = #ID";
var sqlCommand = new SqlCommand(sqlString, sqlConnect);
sqlCommand.Parameters.Add("#ID", SqlDbType.UniqueIdentifier).Value = ID;
using (var reader = sqlCommand.ExecuteReader())
{
while (reader.Read())
{
time = reader["Time"];
dt = DateTime.Parse(time.ToString(), CultureInfo.InvariantCulture);
value = reader["Value"];
insertData(IdDestination, dt, value);
}
}
This function is working, but if I have 10.000 table rows, then it's very slow.
I was thinking about using SqlBulkCopy, but this doesn't work for me because I need to change the Destination ID. Another problem is that sometimes, the values I want to copy already exist, so I need a rollback or commit. Update is also not working because of losing important data.
Does anyone have an idea about what kind of batch processing would work for me?
I'd like to insert 1000 rows or more at the same time without having to call my insert function a thousand times.

Can't retrieve data from the database

I'm a little in need of your help
In my web application I have this Select statement, but once I run it, it retrieves 0 data but when I try my Select statement in the database it has data in it, and my Select statement is correct, by the way my application is already published in the server.
Here's my code
string SelectStatement = "SELECT DATEDIFF(day, kg1653, GETDATE()) datenum, kg1635, (CASE WHEN kg1637 is null THEN 0 END) eis ";
string FromStatement = "FROM hsi.keygroupdata503 ";
string WhereStatement = "WHERE kg1235='" + _securityCode + "' and kg1241 is null";
_sqlDT = ConnectToDatabase(SelectStatement + FromStatement + WhereStatement);
and here's my connection string
System.Data.Odbc.OdbcConnection _odbcConn = new System.Data.Odbc.OdbcConnection();
_odbcConn.ConnectionString = "MY DATABASE CONNECTION STRING";
System.Data.Odbc.OdbcDataAdapter _odbcA = new System.Data.Odbc.OdbcDataAdapter(sqlQuery1, _odbcConn);
DataTable _odbcDt = new DataTable();
_odbcA.Fill(_odbcDt);
return _odbcDt;
Can somebody please help me with this?
Thank you so much!
When does sqlQuery1 get set to _sqlDT ... your best bet is to debug and see what the query is right on the line of it being called and copy it to run on the SQL server in case something else is updating it or _scurityCode is empty. Also if you have a test environment with similar table names, make sure you are connecting to the same live instance.
Side note, not foolproof but make sure _securityCode has a replace statement and change all single quotes to double quotes to work against SQL injection as the commentor above said.