I can't delete selected id data from database in kotlin - kotlin

What should I do at this stage to delete the selected id? I tried all the ways I could think of. thanks
val db = this.writableDatabase
db.delete(table_name, null, null)
val db = this.writableDatabase
db.delete(table_name, "$col_id=?", arrayOf(itemId.toString()) )
Toast.makeText(context, "Silindi", Toast.LENGTH_LONG).show()
db.close()

Try executing a delete query like this
val sql = "DELETE FROM $table_name WHERE $col_id = $itemId"
db.execSQL(sql)
Then show the Toast message to indicate that the item has been deleted, and close the database connection afterwards.

Related

JPA using #ElementCollection with #OrderColumn but it makes exception to 'duplicate key value violates unique constraint'

First of all, I'm n.b to spring and jpa. so, Sorry for the rudimentary question.
These days I tried to make server system to location points storing using springboot + jpa + docker + postgresql /kotlin
my idea is server get client call and store locations periodically
so, I using #ElementCollection for store location item with #Embeddable
but, I got exception from springTest code
Hibernate:
insert
into
pos_info_pos_list
(pos_info_id, pos_list_order, accuracy, event_time, geo_lati, geo_long)
values
(?, ?, ?, ?, ?, ?)
2022-11-12 22:07:34.963 WARN 25880 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23505
2022-11-12 22:07:34.963 ERROR 25880 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: duplicate key value violates unique constraint "pos_info_pos_list_pkey"
Detail: Key (pos_info_id, pos_list_order)=(1, 0) already exists.
I'll explain the table structure below
PosInfo(one), PosData(many)
oneToMany relation
I want to use ordercolumn for performance and want posList size limitation(MAX_POS_DATA_SIZE = 200)
#Entity
data class PosInfo(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
var id: Long? = null
) {
#ElementCollection(fetch = FetchType.EAGER, targetClass = PosData::class)
#OrderColumn
val posList: MutableList<PosData> = mutableListOf()
fun addPosData(posData: PosDataDto) {
while (posList.size >= MAX_POS_DATA_SIZE) {
posList.removeFirst()
}
val newData = PosData(posData.geoLati, posData.geoLong, posData.eventTime, posData.accuracy)
posList.add(newData)
}
}
PosData table
#Embeddable
data class PosData(
#Column
val geoLati: String,
#Column
val geoLong: String,
#Column
val eventTime: Long,
#Column
val accuracy: Int,
)
SpringTestCode is
first of all, insert maxSize posData then add more one data again
#Test
fun addPathMax() {
val dummyPosData = PosDataDto("", "", System.currentTimeMillis(), 0)
val dummyPosData2 = PosDataDto("yyyy", "eeeee", System.currentTimeMillis(), 0)
val id = "KSH"
service.tryAddUser(id, "")
val userInfo = service.getUserInfo(id)
assertThat(userInfo).isNotNull
val posIndex = userInfo!!.posIndex
val posInfo = service.getPosInfo(posIndex)
assertThat(posInfo).isNotNull
for (i in 0 until MAX_POS_DATA_SIZE) {
posInfo!!.addPosData(dummyPosData)
}
service.updatePosInfo(posInfo!!)
println("Next Input Check KSH_TEST")
val posInfo2 = service.getPosInfo(posIndex)
posInfo2!!.addPosData(dummyPosData2)
service.updatePosInfo(posInfo2!!)
}
#Transactional
service.updatePosInfo <= it just call to crudRepository save method
but I got duplicate key again and again
Q1. Shouldn't the 'pos_list_order' be 'existing last +1' since the first data of the previous data was erased and the new data was inserted? why '0'?
// Key (pos_info_id, pos_list_order)=(1, 0) already exists.
Q2. Is this structure not good for updating and storing location data periodically?(using ElementCollection, should I use OneToMany?)
=To be honest, I've tried "one To Many" before. By the way, I gave up because I was tired of fixing strange build errors. I came back with "Element Collection," which I thought was easy
Thank you in advance for all the helpful comments
===========================
= I already tried before below
OneToMany with mapped, but it made many error and when I tried insert more value, it was made all delete row and re-install all and + newer again
ElementCollection looks simple, but it was made duplicated exception again and again
I already checked using below
#CollectionTable(
name = "pos_data",
joinColumns = [JoinColumn(name = "pos_info_id")]
)
JpaRepository.save then flush doesn't work
but same result, I don't know why.. really sad
I got a solution
Now this problem was caused by my poor understanding of 'Transactional'
it's fixed with below annotation
#Transactional(propagation = Propagation.REQUIRES_NEW)
#Transactional(propagation = Propagation.REQUIRES_NEW)
#Rollback(false)
#Test
fun addPathMax() {
val dummyPosData = PosDataDto("", "", System.currentTimeMillis(), 0)
val dummyPosData2 = PosDataDto("yyyy", "eeeee", System.currentTimeMillis(), 0)
val id = "KSH"
service.tryAddUser(id, "")
val userInfo = service.getUserInfo(id)
assertThat(userInfo).isNotNull
val posIndex = userInfo!!.posIndex
val posInfo = service.getPosInfo(posIndex)
assertThat(posInfo).isNotNull
for (i in 0 until Constants.MAX_POS_DATA_SIZE) {
posInfo!!.addPosData(dummyPosData)
}
service.updatePosInfo(posInfo!!)
println("Next Input Check KSH_TEST")
val posInfo2 = service.getPosInfo(posIndex)
posInfo2!!.addPosData(dummyPosData2)
service.updatePosInfo(posInfo2!!)
}
I thought service already including 'Transactional' annotation
so it can be made query persist context to database
but it was not

H2 schema disappears after connection is closed

after setting up a schema in an H2 database for unit testing, the unit tests relying on the schema could not find it.
import java.sql.DriverManager
Class.forName("org.h2.Driver")
val setupConn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;MODE=PostgreSQL", "sa", "")
val setupStmt = setupConn.createStatement
// setup schema at the beginning of our test
setupStmt.execute("CREATE SCHEMA IF NOT EXISTS my_test_schema AUTHORIZATION sa;")
setupStmt.execute("GRANT ALL ON SCHEMA my_test_schema TO sa;")
setupStmt.execute("CREATE TABLE IF NOT EXISTS my_test_schema.my_test_table (test_id VARCHAR(255), test_column VARCHAR(255));")
setupStmt.executeQuery("select * from my_test_schema.my_test_table")
// res4: java.sql.ResultSet = rs3: org.h2.result.LocalResultImpl#3eb10d62 columns: 2 rows: 0 pos: -1
// this seems to work correctly ^^^
setupStmt.close
setupConn.close
// now run our test using the schema we just set up
val conn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;SCHEMA=my_test_schema;MODE=PostgreSQL", "sa", "")
val stmt = conn.createStatement
stmt.executeQuery("select * from my_test_table where test_id = '1'")
// org.h2.jdbc.JdbcSQLSyntaxErrorException: Schema "MY_TEST_SCHEMA" not found; SQL statement:
// SET SCHEMA my_test_schema [90079-200]
// ^^^^ something has gone horribly wrong
You can simply add ;DB_CLOSE_DELAY=-1 to the JDBC URL; no need to have an active connection.
https://h2database.com/html/commands.html#set_db_close_delay
If you use a some recent version of H2, you may also want to add ;DATABASE_TO_LOWER=TRUE for better compatibility with PostgreSQL; the PostgreSQL compatibility mode by itself doesn't imply this setting.
This is embarrassing, but I didn't realize that when I closed the connection to my in memory database, the database would dry up and blow away. This seems obvious in retrospect. The solution is to keep the first connection to the database open throughout testing.
import java.sql.DriverManager
Class.forName("org.h2.Driver")
val setupConn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;MODE=PostgreSQL", "sa", "")
val setupStmt = setupConn.createStatement
// setup schema at the beginning of our test
setupStmt.execute("CREATE SCHEMA IF NOT EXISTS my_test_schema AUTHORIZATION sa;")
setupStmt.execute("GRANT ALL ON SCHEMA my_test_schema TO sa;")
setupStmt.execute("CREATE TABLE IF NOT EXISTS my_test_schema.my_test_table (test_id VARCHAR(255), test_column VARCHAR(255));")
setupStmt.executeQuery("select * from my_test_schema.my_test_table")
// res4: java.sql.ResultSet = rs3: org.h2.result.LocalResultImpl#3eb10d62 columns: 2 rows: 0 pos: -1
// DON'T CLOSE THE CONNECTION YET!
//setupStmt.close
//setupConn.close
val conn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;SCHEMA=my_test_schema;MODE=PostgreSQL", "sa", "")
val stmt = conn.createStatement
stmt.executeQuery("select * from my_test_table where test_id = '1'")
// res5: java.sql.ResultSet = rs4: org.h2.result.LocalResultImpl#293e66e4 columns: 2 rows: 0 pos: -1
// ^^^^ huzzah!

Multiple SQL statements using Groovy

Delete multiple entries from DB using Groovy in SoapUI
I am able to execute one SQL statement, but when I do a few it just hangs.
How can I delete multiple rows?
def sql = Sql.newInstance('jdbc:oracle:thin:#jack:1521:test1', 'test', 'test', 'oracle.jdbc.driver.OracleDriver')
log.info("SQL connetced")
sql.connection.autoCommit = false
try {
log.info("inside try")
log.info("before")
String Que =
"""delete from table name where user in (select user from user where ID= '123' and type= 262);
delete from table name where user in (select user from user where ID= '1012' and type= 28)
delete from table name where user in (select user from user where ID= '423' and type= 27)
"""
log.info (Que)
def output = sql.execute(Que);
log.info(sql)
log.info(output)
log.info("after")
sql.commit()
println("Successfully committed")
}catch(Exception ex) {
sql.rollback()
log.info("Transaction rollback"+ex)
}
sql.close()
Here is what you are looking for.
I feel it is more effective way if you want bulk number of records using the following way.
Create a map for the data i.e., id, type as key value pair that needs to be removed in your case.
Used closure to execute the query by iterating thru it.
Added comments appropriately.
//Closure to execute the query with parameters
def runQuery = { entry ->
def output = sql.execute("delete from table name where user in (select user from user where ID=:id and type=:type)", [id:entry.key, type:entry.value] )
log.info(output)
}
//Added below two statements
//Create the data that you want to remove in the form of map id, and type
def deleteData = ['123':26, '1012':28, '423':27]
def sql = Sql.newInstance('jdbc:oracle:thin:#jack:1521:test1', 'test', 'test', 'oracle.jdbc.driver.OracleDriver')
log.info("SQL connetced")
sql.connection.autoCommit = false
try {
log.info(sql)
log.info("inside try")
log.info("before")
//Added below two statements
//Call the above closure and pass key value pair in each iteration
deleteData.each { runQuery(it) }
log.info("after")
sql.commit()
println("Successfully committed")
}catch(Exception ex) {
sql.rollback()
log.info("Transaction rollback"+ex)
}
sql.close()
If you are just looking after execution of multiple queries only approach, then you may look at here and not sure if your database supports the same.

using sql reader to check for nulls when setting multiple values

I have a sql command that is picking up a row in my DB but sometimes one of the datetime values may be null.
example:
var reader = command.ExecuteReader();
if (reader.HasRows)
{
List<AdmissionsVm> appDetailsOut = new List<AdmissionsVm>();
while (reader.Read())
{
appListOut.Add(new AdmissionsVm
{
Parish = Convert.ToString(reader.GetValue(40)),
CofE = Convert.ToBoolean(reader.GetValue(41)),
OtherFaith = Convert.ToString(reader.GetValue(42)),
PrefSiblingName1 = Convert.ToString(reader.GetValue(43)),
if (!reader.GetValue(44).IsDbNull){SiblingDateOfBirth = Convert.ToDateTime(reader.GetValue(44))}
SiblingGender = Convert.ToString(reader.GetValue(45))
});
}
}
I am actually bringing back a lot of details but when the siblingdateofbirth is null, i cant seem to check it as i am getting errors with fields that have been added afterwards
any help would be appreciated
Its often better to specify the column name instead of the column position because if the query for some reason changes the order in which its returning columns, you may need to change the params of all the GetValue calls.
To check for null try something like this
if (!reader.IsDBNull(reader.GetOrdinal("YourColumnNameForPosition44")))
{SiblingDateOfBirth = Convert.ToDateTime(reader.GetString(reader.GetOrdinal("YourColumnAgain"))}

MS Access ##identity query issue

Can someone please let me know the issue with the below query? I am running on MS Access and its giving
Syntax error in query expression 'id = ##IDENTITY'
Code:
public DosageBO SaveDosage(DosageBO dosage)
{
try
{
using (IDbConnection connection = OpenConnection())
{
StringBuilder sql = new StringBuilder();
sql.AppendLine("INSERT INTO dosage_master ( medicine_type, dosage, remarks, updateby, updatedate )");
sql.AppendLine("VALUES (#type, #dose, #remarks, #updateby, NOW());");
var parameters = new
{
type = dosage.MedicineType,
dose = dosage.Dosage,
remarks = dosage.Remarks,
updateby = Environment.UserName
};
connection.Execute(sql.ToString(), parameters);
return connection.Query<DosageBO>("SELECT medicine_type as MedicineType, dosage, remarks FROM dosage_master WHERE id = ##IDENTITY").FirstOrDefault();
}
}
catch
{
throw;
}
}
SELECT ##Identity is a specialized query. And ##Identity is only valid in that context. If you attempt to use ##Identity elsewhere, as in a WHERE clause, the db engine will throw an error.
You will have to retrieve the value from SELECT ##Identity, save it, and then use that saved value in your other query.
Remove the ) at the end
WHERE id = ##IDENTITY)
^---here
Are you inserting a row in this batch prior to the select query?
To my knowledge ##IDENTITY is only available directly after inserting a row causing an identity value to be generated i.e an insert to an autoincremental identity column.
Edit again:
Try enclosing it in a subquery e.g id = (SELECT ##IDENTITY)