Delete one row from the database - sql

I'm having a problem deleting just one row. I can insert and delete the whole table. I'm not able to understand the whole ID thing in order to delete just one row. I was looking at some examples, but I couldn't get it. It’s driving me crazy.
Here is the SQLite class;
public class datahelper {
private static final String DATABASE_NAME = "table.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "table1";
private Context context;
private SQLiteDatabase db;
private SQLiteStatement insertStmt;
private static final String INSERT =
"insert into " + TABLE_NAME + "(name) values (?)";
public datahelper(Context context) {
this.context = context;
OpenHelper openHelper = new OpenHelper(this.context);
this.db = openHelper.getWritableDatabase();
this.insertStmt = this.db.compileStatement(INSERT);
}
public long insert(String name) {
this.insertStmt.bindString(1, name);
return this.insertStmt.executeInsert();
}
public long insert2(String name) {
this.insertStmt2.bindString(1, name);
return this.insertStmt2.executeInsert();
}
public void deleteAll() {
this.db.delete(TABLE_NAME, null, null);
}
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME +
" (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)");
}
}

Execute the query
DELETE FROM TABLE_NAME WHERE id = SOMEVALUE

It looks like you are using this API, which provides this delete method. My guess is that you would do this:
public void delete(int id) {
this.db.delete(TABLE_NAME, 'id = ?', new String[] { id.toString() });
}
(Original answer...)
Use a DELETE statement with a WHERE clause that deletes only the row with the id you want to remove:
DELETE FROM <tablename> WHERE id = ?
Of course, you need to know the id in order to do this. SQLite provides a function — sqlite3_last_insert_rowid() — that you can call immediately after an INSERT. If your API doesn't provide this function directly, you can get it indirectly via the equivalent SQL function:
SELECT last_insert_rowid()
Alernatively if you want to delete a certain name (assuming it's unique):
DELETE FROM <tablename> WHERE name = ?

Related

How to search a non-primary attribute from DynamoDB with Spring Reactive (Webflux)?

Suppose I have user table with fields userId, userName, password and some other fields where userId is the partition key. How could I write a query to find something from userName and not from userId? I am working with Spring webflux, so it also does not have the ReactiveCrudRepository for DynamoDb. My User table is something like this:
#Data
#NoArgsConstructor
#AllArgsConstructor
#DynamoDbBean
public class User {
private String userId;
private String userName;
private String password;
private String firstName;
private String lastName;
private String timestamp;
#DynamoDbPartitionKey
public String getUserId() {
return userId;
}
}
My repo class is:
#Repository
public class UserRepo {
private DynamoDbAsyncTable<User> userDynamoDbAsyncTable;
public UserRepo(DynamoDbAsyncTable<User> userDynamoDbAsyncTable) {
this.userDynamoDbAsyncTable = userDynamoDbAsyncTable;
}
// CREATE
public CompletableFuture<Void> save(User user) {
return userDynamoDbAsyncTable.putItem(user);
}
// READ
public CompletableFuture<User> getUserByID(String userId) {
return userDynamoDbAsyncTable.getItem(getKeyBuild(userId));
}
// UPDATE
public CompletableFuture<User> updateUser(User user) {
return userDynamoDbAsyncTable.updateItem(user);
}
// DELETE
public CompletableFuture<User> deleteUserById(String userId) {
return userDynamoDbAsyncTable.deleteItem(getKeyBuild(userId));
}
// GET_ALL_ITEM
public PagePublisher<User> getAllUser() {
return userDynamoDbAsyncTable.scan();
}
private Key getKeyBuild(String userId) {
return Key.builder().partitionValue(userId).build();
}
}
Is there any way to query database something like findByUserName("John") which returns the User object with "John" as a username?
You can't query without a partition key, if you have the partition key you can combine that with a sortKey, otherwise you will need to make your userName field a sortKey in Dynamo and use a GlobalSecondaryIndex to be able to search by userName alone.
#DynamoDbSortKey
public String getUserName() {
return serName;
}
You could use table.scan() but that's not recommended, the recommended way is to use a partition key + sortKey or sortKey + GlobalSecondaryIndex with the table method table.query().

Ignore properties in data model while keeping them in EF Core migrations and Database Tabel

I have properties in my Model like
public class Test{
public int Id{ get; set; }
public string Title { get; set; }
public DateTime? CreatedDate { get; set; }
public DateTime? ModifiedDate { get; set; }
public DateTime? DeletedDate { get; set; }
}
Here, I am using this Test class for creating Table in Database using Migration,
Now the table is created successfully but the problem is when i want do any operation using stored procedure which is like " Select Title from Test where Id=1" ,When i run the this i am facing error like this
"The required column 'CreatedDate' was not present in the results of a
'FromSql' operation"
I have used
NotMapped Attribute it works fine but when i add another migration the NotMapped properties gets Dropped from the database after updating the database
Also use Shadow properties and Ignore properties like
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Test>().Property<DateTime?>("CreatedDate");
modelBuilder.Entity<Test>().Property<DateTime?>("ModifiedDate");
modelBuilder.Entity<Test>().Property<DateTime?>("DeletedDate");
}
Also try this,
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<Test>().Ignore(x => x.DeletedDate);
modelBuilder.Entity<Test>().Ignore(x => x.IsDeleted);
modelBuilder.Entity<Test>().Ignore(x => x.ModifiedDate); }
But the issue remains the same ,
So the issue is i want to ignore the CreateDate, ModifiedDated, DeletedDated property while performing DB operation and also not want to drop these columns from Database when i add and update new migration.
"The required column 'CreatedDate' was not present in the results of a
'FromSql' operation"
The first thing you need to know is that the root problem of this error is not your CreatedDate field, but the type you return after executing FromSql.
When you execute FromSql, the return type is Test, and the Test type contains all fields(Id,Title,CreatedDate...), but your stored procedure only selects the Title field,therefore, the received type does not match, and this error occurs.
You can solve this problem from two methods.
The first method is to change the stored procedure to return data consistent with the Test type.
Select * from Test where Id=1
The other method changes from the perspective of receiving types.
You can customize the FromSql method to make the returned type dynamic.
public static class CustomFromSqlTest
{
public static IEnumerable<dynamic> FromSql(this DbContext dbContext, string Sql, Dictionary<string, object> Parameters)
{
using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
{
cmd.CommandText = Sql;
if (cmd.Connection.State != ConnectionState.Open)
cmd.Connection.Open();
foreach (KeyValuePair<string, object> param in Parameters)
{
DbParameter dbParameter = cmd.CreateParameter();
dbParameter.ParameterName = param.Key;
dbParameter.Value = param.Value;
cmd.Parameters.Add(dbParameter);
}
//var retObject = new List<dynamic>();
using (var dataReader = cmd.ExecuteReader())
{
while (dataReader.Read())
{
var dataRow = GetDataRow(dataReader);
yield return dataRow;
}
}
}
}
private static dynamic GetDataRow(DbDataReader dataReader)
{
var dataRow = new ExpandoObject() as IDictionary<string, object>;
for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
dataRow.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
return dataRow;
}
}
Use it:
var result = _context.FromSql("spName #Id", new Dictionary<string, object> { { "#Id", 1 } }).ToList();

Querydsl nested query generated an error sql

I wrote a simple nested query
#Autowired
#PersistenceContext
EntityManager entityManager;
#Autowired
Configuration configuration;
private JPASQLQuery<?> queryFactory;
#PostConstruct
public void init() {
queryFactory = new JPASQLQuery<>(entityManager, configuration);
}
public void student() {
QStudent student = new QStudent("student");
QStudent nested = new QStudent("nested");
List<?> fetch = queryFactory.select(student.id)
.from(SQLExpressions.select(nested.id)
.from(nested), student)
.fetch();
}
The entity structure is like this
#Entity
#Table(name = "u_student")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
The generated sql is like this
select student.id
from u_student (select nested.id
from u_student nested) as student
Outside sql added a tableName up, causing sql syntax error
Am I wrong? How should such a nested query be written?
The first time you send a question is not very useful, thank you.
Found that using PathBuilder can solve this problem
The complete code is:
PathBuilder<Tuple> studentAlias = new PathBuilder<>(Tuple.class,"student");
QStudent student = new QStudent("student");
QStudent nested = new QStudent("nested");
List<?> fetch = queryFactory.select(student)
.from(SQLExpressions.select(nested.id)
.from(nested), studentAlias)
.fetch();
Generated sql:
select student.id as id1_90_0_
from (select nested.id from u_student nested) as student
Do you have any better plans?

Error in insert statement for HSQL DB

I have Spring data rest application & for unit testing these services, I am using Spring Boot & HSQL in memory databse. But while inserting data into the HSQL table at runtime, I am getting an error. While other insert statements are working, I am getting this error only for 1 insert statement.
Error
Caused by: java.sql.SQLException: Column count does not match in statement
Insert Statement in SQL file
Insert into countries (ID,COUNTRY,CODE) values (2,'UNITED STATES','US');
Note:- In the same application insert for other tables are working & retrieval of the data from the table is also successful.
Entity - Using this HSQL create the table.
#Entity
#Table(name = "COUNTRIES")
public class Country implements Describable, Serializable {
#Id
#SequenceGenerator(name="CountriesSeq",sequenceName="SEQ_COUNTRIES")
#GeneratedValue(strategy = GenerationType.AUTO, generator = "CountriesSeq")
protected Integer id;
#Column(name = "CODE")
private String code;
#Column(name = "COUNTRY")
private String country;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Thanks
This issue is resolved. The table had trigger on it which I didnt notice. Thanks for your input Acewin.

How to Customize index using code first? [duplicate]

Is there any way to implement the Guid COMB identity strategy for objects in the new Entity Framework 4.1 using the CodeFirst design? I thought setting the StoreGeneratedPattern would work, but it still gives me normal GUIDs.
Why worry about defaults for Guid columns in the database at all? Why not just generate the Guid on the client like any other value. That requires you have a method in your client code that will generate COMB-like guids:
public static Guid NewGuid()
{
var guidBinary = new byte[16];
Array.Copy( Guid.NewGuid().ToByteArray(), 0, guidBinary, 0, 8 );
Array.Copy( BitConverter.GetBytes( DateTime.Now.Ticks ), 0, guidBinary, 8, 8 );
return new Guid( guidBinary );
}
One of the advantages of the Guid is specifically that you can generate them on the client without a round trip to the database.
I guess you are using SQL server as your database. This is nice example of inconsistency among different MS tools. SQL server team doesn't recommend using newid() as default value for UNIQUEIDENTIFIER columns and ADO.NET team use it if you specify Guid property as autogenerated in the database. They should use newsequentialid() instead!
If you want sequential Guids generated by database you must modify generated table and it is really complex because you must find autogenerated default constraint, drop it and create new constraint. This all can be done in custom database initializer. Here you have my sample code:
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new CustomInitializer());
using (var context = new Context())
{
context.TestEntities.Add(new TestEntity() { Name = "A" });
context.TestEntities.Add(new TestEntity() { Name = "B" });
context.SaveChanges();
}
}
}
public class CustomInitializer : DropCreateDatabaseAlways<Context>
{
protected override void Seed(Context context)
{
base.Seed(context);
context.Database.ExecuteSqlCommand(#"
DECLARE #Name VARCHAR(100)
SELECT #Name = O.Name FROM sys.objects AS O
INNER JOIN sys.tables AS T ON O.parent_object_id = T.object_id
WHERE O.type_desc LIKE 'DEFAULT_CONSTRAINT'
AND O.Name LIKE 'DF__TestEntities__Id__%'
AND T.Name = 'TestEntities'
DECLARE #Sql NVARCHAR(2000) = 'ALTER TABLE TestEntities DROP Constraint ' + #Name
EXEC sp_executesql #Sql
ALTER TABLE TestEntities
ADD CONSTRAINT IdDef DEFAULT NEWSEQUENTIALID() FOR Id");
}
}
public class TestEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Context : DbContext
{
public DbSet<TestEntity> TestEntities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<TestEntity>()
.Property(e => e.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
The simplest answer
public class User
{
public User(Guid? id = null, DateTime? created = null)
{
if (id != null)
Id = id;
if (created != null)
Created = created;
}
public User()
{
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime? Created { get; internal set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid? Id { get; internal set; }
}
This assumes you have your database table set with the default of newsequentialid() which in my case is managed by FluentMigrator migrations.
if you use SQL Server, when a GUID property is configured as value generated on add, the provider automatically performs value generation client-side, using an algorithm to generate optimal sequential GUID values. refer to for more.
https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=fluent-api