How I can write a JDBC request with two WHERE clauses.
When I only one WHERE cluse the request is fine.
// example of array
String[] listeId1 = null;
listeId1[0] =['0'];
listeId1[1] =['1'];
String[] listeId = null;
listeId[0] = ['00']
listeId[1] = ['01']
//I don't know how many elements there will be in listeId1 and listeId
String inClause = "?";
int i = 1;
while (i <= listeId.length - 1 ) {
inClause += ",?";
i++;
}
//my request
List<Map<String, Object>> result = this.getJdbcTemplate()
.queryForList("SELECT * FROM TABLE_FONCTION " +
"WHERE ROLE_ID IN (" + inClause + ")" , listeId
+ " AND PROCESSUS_ID IN (" + inClause1 + ")" ,listeId1 )
;
// Definition of my table
CREATE TABLE TABLE_FONCTION (
FONCTION_ID NUMBER(18) NOT NULL,
ACTIVE CHAR(1) NOT NULL,
TYPE_FONCTION_ID NUMBER(18) NOT NULL,
PROCESSUS_ID NUMBER(18) NOT NULL,
ROLE_ID NUMBER(18) NOT NULL
);
What's wrong with my request ?
You never defined inClause1; in particular, before using it to build your query.
Related
Ok , I"m doing what looks like a simple Dapper query
but if I pass in my studId parameter, it blows up with this low level networking exception:
{"A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied."}
if I comment out the line of sql that uses it, fix the where clause, ,and comment out the line where it's added the the parameters object. It retrieves rows as expected.
I've spent the last 2.5 days trying everything I could think of, changing the names to match common naming patterns, changing type to a string (just gave a error converting string to number), yadda yadda yadda..
I'm at a complete loss as to why it doesn't like that parameter, I look at other code that works and they pass Id's just fine...
At this point I figure it has to be an ID-10-t that's staring me in the face and I'm just assuming my way right past it with out seeing it.
Any help is appreciated
public List<StudDistLearnSchedRawResponse> GetStudDistanceLearningScheduleRaw( StudDistLearnSchedQueryParam inputs )
{
var aseSqlConnectionString = Configuration.GetConnectionString( "SybaseDBDapper" );
string mainSql = " SELECT " +
" enrollment.stud_id, " +
" sched_start_dt, " +
" sched_end_dt, " +
" code.code_desc, " +
" student_schedule_dl.enrtype_id, " +
" student_schedule_dl.stud_sched_dl_id, " +
" dl_correspond_cd, " +
" course.course_name, " +
" stud_course_sched_dl.sched_hours, " +
" actual_hours, " +
" course_comments as staff_remarks, " + // note this column rename - EWB
" stud_course_sched_dl.sched_item_id , " +
" stud_course_sched_dl.stud_course_sched_dl_id " +
" from stud_course_sched_dl " +
" join student_schedule_dl on student_schedule_dl.stud_sched_dl_id = stud_course_sched_dl.stud_sched_dl_id " +
" join course on stud_course_sched_dl.sched_item_id = course.sched_item_id " +
" left join code on student_schedule_dl.dl_correspond_cd = code.code_id " +
" join enrollment_type on student_schedule_dl.enrtype_id = enrollment_type.enrtype_id " +
" join enrollment on enrollment_type.enr_id = enrollment.enr_id " +
" where enrollment.stud_id = #studId " +
" and sched_start_dt >= #startOfWeek" +
" and sched_end_dt <= #startOfNextWeek";
DapperTools.DapperCustomMapping<StudDistLearnSchedRawResponse>();
//string sql = query.ToString();
DateTime? startOfWeek = StartOfWeek( inputs.weekStartDateTime, DayOfWeek.Monday );
DateTime? startOfNextWeek = StartOfWeek( inputs.weekStartDateTime.Value.AddDays( 7 ) , DayOfWeek.Monday );
try
{
using ( IDbConnection db = new AseConnection( aseSqlConnectionString ) )
{
db.Open();
var arguments = new
{
studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
startOfWeek = startOfWeek.Value.ToShortDateString(),
startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
List<StudDistLearnSchedRawResponse> list = new List<StudDistLearnSchedRawResponse>();
list = db.Query<StudDistLearnSchedRawResponse>( mainSql, arguments ).ToList();
return list;
}
}
catch (Exception ex)
{
Trace.WriteLine(ex.ToString());
return null;
}
}
Here is the input object
public class StudDistLearnSchedQueryParam
{
public Int64 StudId;
public DateTime? weekStartDateTime;
}
Here is the dapper tools object which just abstracts some ugly code to look nicer.
namespace EricSandboxVue.Utilities
{
public interface IDapperTools
{
string ASEConnectionString { get; }
AseConnection _aseconnection { get; }
void ReportSqlError( ILogger DalLog, string sql, Exception errorFound );
void DapperCustomMapping< T >( );
}
public class DapperTools : IDapperTools
{
public readonly string _aseconnectionString;
public string ASEConnectionString => _aseconnectionString;
public AseConnection _aseconnection
{
get
{
return new AseConnection( _aseconnectionString );
}
}
public DapperTools( )
{
_aseconnectionString = Environment.GetEnvironmentVariable( "EIS_ASESQL_CONNECTIONSTRING" );
}
public void ReportSqlError( ILogger DalLog, string sql, Exception errorFound )
{
DalLog.LogError( "Error in Sql" );
DalLog.LogError( errorFound.Message );
//if (env.IsDevelopment())
//{
DalLog.LogError( sql );
//}
throw errorFound;
}
public void DapperCustomMapping< T >( )
{
// custom mapping
var map = new CustomPropertyTypeMap(
typeof( T ),
( type, columnName ) => type.GetProperties( ).FirstOrDefault( prop => GetDescriptionFromAttribute( prop ) == columnName )
);
SqlMapper.SetTypeMap( typeof( T ), map );
}
private string GetDescriptionFromAttribute( System.Reflection.MemberInfo member )
{
if ( member == null ) return null;
var attrib = (Dapper.ColumnAttribute) Attribute.GetCustomAttribute( member, typeof(Dapper.ColumnAttribute), false );
return attrib == null ? null : attrib.Name;
}
}
}
If I change the SQL string building to this(below), but leave everything else the same(Including StudId in the args struct)... it doesn't crash and retrieves rows, so it's clearly about the substitution of #studId...
// " where enrollment.stud_id = #studId " +
" where sched_start_dt >= #startOfWeek" +
" and sched_end_dt <= #startOfNextWeek";
You name your data members wrong. I had no idea starting a variable name with # was possible.
The problem is here:
var arguments = new
{
#studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
#startOfWeek = startOfWeek.Value.ToShortDateString(),
#startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
It should have been:
var arguments = new
{
studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
startOfWeek = startOfWeek.Value.ToShortDateString(),
startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
The # is just a hint to Dapper, that it should replace with a corresponding member name.
## has special meaning in some SQL dialects, that's probably what makes the trouble.
So here's what I Found out.
The Sybase implementation has a hard time with Arguments.
It especially has a hard time with arguments of type int64 (this existed way pre .NetCore)
So If you change the type of the passed in argument from int64 to int32, everything works fine.
You can cast it, or just change the type of the method parameter
I don't know what is the problem because the MEMBER table has a primary key..
void setupBookTable() {
String TABLE_NAME = "BOOK";
try {
stmt = conn.createStatement();
DatabaseMetaData dbm = conn.getMetaData();
ResultSet tables = dbm.getTables(null,null, TABLE_NAME.toUpperCase(),null);
if (tables.next()) {
System.out.println("A " + TABLE_NAME + " már készen áll!");
} else {
stmt.execute("CREATE TABLE " + TABLE_NAME + "("
+ " id varchar(200) primary key,\n"
+ " title varchar(200),\n"
+ " author varchar(200),\n"
+ " publisher varchar(200),\n"
+ " isAvail boolean default true"
+ " )");
}
} catch (SQLException e) {
System.err.println(e.getMessage() + " .. setupDatabase");
} finally {
}
}
void setupMemberTable() {
String TABLE_NAME = "MEMBER";
try {
stmt = conn.createStatement();
DatabaseMetaData dbm = conn.getMetaData();
ResultSet tables = dbm.getTables(null,null, TABLE_NAME.toUpperCase(),null);
if (tables.next()) {
System.out.println("A " + TABLE_NAME + " asztal már készen áll!");
} else {
stmt.execute("CREATE TABLE " + TABLE_NAME + "("
+ "name varchar(50), "
+ "ID varchar(100) primary key, "
+ "mobile varchar(25), "
+ "email varchar(100))");
}
} catch (SQLException e) {
System.err.println(e.getMessage() + " .. setupDatabase");
} finally {
}
}
void setupKiadTable() {
String TABLE_NAME = "KIAD";
try {
stmt = conn.createStatement();
DatabaseMetaData dbm = conn.getMetaData();
ResultSet tables = dbm.getTables(null, null, TABLE_NAME.toUpperCase(), null);
if (tables.next()){
System.out.println("A " + TABLE_NAME + " asztal már készen áll!");
} else {
stmt.execute("CREATE TABLE " + TABLE_NAME + "("
+ " bookID varchar(200) primary key,\n"
+ " memberID varchar(200),\n"
+ " kiadTime timestamp default CURRENT_TIMESTAMP,\n"
+ " megujit_count integer default 0,\n"
+ " FOREIGN KEY (bookID) REFERENCES BOOK(id),\n"
+ " FOREIGN KEY (memberID) REFERENCES MEMBER(ID))\n");
}
} catch (SQLException e) {
System.err.println(e.getMessage() + " --- adatbázis felállítás");
} finally {
}
}
I got this error:
"Constraint 'SQL190509155106120' is invalid: there is no unique or
primary key constraint on table '"APP"."MEMBER"' that matches the
number and types of the columns in the foreign key. --- adatbázis
felállítás"
I found this search example in PostgreSQL http://www.postgresql.org/docs/current/interactive/textsearch-tables.html#TEXTSEARCH-TABLES-SEARCH
I tried to implement this code for this table this way:
CREATE TABLE ACCOUNT(
ID INTEGER NOT NULL,
USER_NAME TEXT,
PASSWD TEXT,
FIRST_NAME TEXT,
LAST_NAME TEXT,
LAST_LOGIN DATE,
DATE_REGISTERED DATE,
ROLE INTEGER,
CAN_LOGIN INTEGER
)
;
-- ADD KEYS FOR TABLE ACCOUNT
ALTER TABLE ACCOUNT ADD CONSTRAINT KEY1 PRIMARY KEY (ID)
;
Java code
public List<AccountsObj> list(int firstRow, int rowCount, String sortField, boolean sortAscending) throws SQLException
{
String SqlStatement = null;
Connection conn = ds.getConnection();
if (conn == null)
{
throw new SQLException();
}
String sortDirection = sortAscending ? "ASC" : "DESC";
SqlStatement = "SELECT * FROM ACCOUNT "
// + " WHERE ? IS NULL OR ? IN (USER_NAME, FIRST_NAME, LAST_NAME)"
+ " WHERE to_tsvector('english', USER_NAME || ' ' ) ## plainto_tsquery(?)"
+ " ORDER BY %S %S offset ? limit ? ";
String sql = String.format(SqlStatement, sortField, sortDirection);
PreparedStatement ps = null;
ResultSet resultSet = null;
List<AccountsObj> resultList = new ArrayList<>();
try
{
conn.setAutoCommit(false);
boolean committed = false;
ps = conn.prepareStatement(sql);
ps.setString(1, searchString);
ps.setInt(2, firstRow);
ps.setInt(3, rowCount);
resultSet = ps.executeQuery();
resultList = ProcessorArrayList(resultSet);
conn.commit();
committed = true;
}
finally
{
ps.close();
conn.close();
}
return resultList;
}
But I have two issues. When search string is empty the table is also empty. How I can solve this? Also how I can implement this search for every table column?
P.S I tried WHERE to_tsvector('english', USER_NAME || ' ' ) ## plainto_tsquery(?) IS NOT NULL
But search filter is not applied.
You will have to add your 'null guard' to the the fulltext search and use to_tsquery instead of plainto_tsquery (in order for prefix search to work).
SqlStatement = "SELECT * FROM ACCOUNT "
+ " WHERE (trim(?) = '') IS NOT FALSE"
+ " OR to_tsvector('english', USER_NAME || ' ' || FIRST_NAME || ' ' || LAST_NAME ) ## to_tsquery(?)"
+ " ORDER BY user_name ASC offset ? limit ? ";
and add the searchString to your PreparedStatement a second time
ps = conn.prepareStatement(sql);
ps.setString(1, searchString);
ps.setString(2, searchString);
ps.setInt(3, firstRow);
ps.setInt(4, rowCount);
Note using a fulltext search you will not be able to search for word-parts (like %user%, %name or us%name). You can search for prefixes though, e.g. user:*
I am using sql prepared statements in my application.
The statements are prepared fine and executed fine.
After that ,when I see the table, there are no entries.
Code snippet:
void DirEntTable::do_init()
{
m_insertIntoSrvrEntTable.setStatement("INSERT INTO " + tableName() + " (entKey, srvrType, serverID, serverEntID) VALUES (" + entKeyField + ", " + srvrTypeField + ", " + serverIDField + ", " + serverEntIDField + ")");
m_insertIntoSrvrEntTable.setConnection(m_db);
if ((rc = m_insertIntoSrvrEntTable.prepare()) != SQLITE_OK)
{
LOGDEBUG("DirEntTable", "insertIntoSrvrEntTable prepare failed (%d) table %s\n", rc, tableName().c_str());
}
}
eErrorT DirEntTable::insertIntoSrvrEntTable(const int entryId, const int serverType,
const std::string &serverID, const std::string &serverEntID)
{
LOGDEBUG(__FUNCTION__, "\nvalues : entryId = %d, serverType = %d, serverID = %s, serverEntID =%s\n",entryId,serverType,serverID.c_str(),serverEntID.c_str());
eErrorT rc = kNoError;
m_insertIntoSrvrEntTable.bindInt(entKeyField, entryId);
m_insertIntoSrvrEntTable.bindInt(srvrTypeField, serverType);
m_insertIntoSrvrEntTable.bindText(serverIDField, serverID);
m_insertIntoSrvrEntTable.bindText(serverEntIDField, serverEntID);
if (!m_insertIntoSrvrEntTable())
{
rc = kFuncReturnedError;
}
m_insertIntoSrvrEntTable.reset();
return rc;
}
Output:
values : entryId = 46, serverType = 2, serverID = gds0, serverEntID =gds:330
query "INSERT INTO gdsEntries (entKey, srvrType, serverID, serverEntID) VALUES (:entKey, :srvrType, :serverID, :serverEntID)"
Please help me in understanding what could be wrong.
Hi guys I want to get the summation of column values from my sqlite database in android.
and am trying to use this to get me the sum of column KEY_COST.
public Cursor fetchAllCost() {
return mDb.query(
DATABASE_TABLE,
new String[] { "SUM(KEY_COST)"},
null,
null,
null,
null,
null);
}
but its giving me a cursor and I do not know how to get the value from the Cursor object. Any one help!!!
You can return scalar values like so:
public int getColumnData() {
mDb = mDbManager.getReadableDatabase();
final SQLiteStatement stmt = mDb
.compileStatement("SELECT SUM(KEY_COST) FROM...");
// Cast as appropriate
return (int) stmt.simpleQueryForLong();
}
Or alternatively, depending on the data type use simpleQueryForString().
You should just move to the first result in the cursor with cursor.moveFirst() and then you can do cursor.getInt(1) to get the scalar value.
rawQuery
Sum value is on first column - cursor.getInt(0);
Cursor cursor = database.rawQuery(
"SELECT SUM(" + COL_NAME + ") FROM " + TABLE_NAME, null);
if(cursor.moveToFirst()) {
return cursor.getInt(0);
}
query
String[] columns = new String[] {
"sum(" + DbHelper.C_COUNT_OF_WORDS + ")"
};
String where = null;
String whereArgs[] = null;
String groupBy = null;
String having = null;
String order = null;
String limit = null;
database = dbHelper.getReadableDatabase();
Cursor cursor = database.query(DbHelper.TABLE_STATISTICS, columns, where, whereArgs, groupBy, having, order, limit);
if(cursor.moveToFirst()) {
return cursor.getInt(0);
}