DbUnit - Delete rows based on non-primary key field value - junit

It looks like DbUnit is using JDBC metadata to determine the primary key fields and constructing delete statement using those field:
delete from tbl_name where pk_field1=? and pk_field2=? and pk_field3=?
Is there a way to delete rows based on one field value of a composite key or value of a non-primary key field (e.g. delete rows where created_date = xyz)

You can create a QueryDataSet and set DatabaseOperation to DELETE.
For exemple, if you are extending DBTestCase:
protected IDataSet getDataSet() {
QueryDataSet queryDataSet = null;
String query = "SELECT * FROM tbl_name pk_field1=? and pk_field2=?";
try {
queryDataSet = new QueryDataSet(super.getConnection());
queryDataSet.addTable("tbl_name",query);
} catch (Exception e) {
e.printStackTrace();
}
return queryDataSet;
}
protected DatabaseOperation getSetUpOperation() throws Exception {
return DatabaseOperation.DELETE;
}

Related

set id value in AUTO_INCREMENT field with laravel

I have tried to set value id of new row in laravel 5 , by Point::create($value) and new Point($value) the $value contains a id value and this id doesn't exist in mysql db.
and every time I try the new row has got a auto id not that in $value
Add id in your fillable array in Point model class.
protected $fillable = [
'id'
];
You need to set a custom primary key with:
protected $primaryKey = 'custom_key';
If you don't have PK, do this:
protected $primaryKey = null;
public $incrementing = false;
Also, remove it from fillable() array. In this case, id will be ignored.
From the docs:
Eloquent will also assume that each table has a primary key column named id. You may define a protected $primaryKey property to override this convention.
In addition, Eloquent assumes that the primary key is an incrementing integer value, which means that by default the primary key will be cast to an int automatically. If you wish to use a non-incrementing or a non-numeric primary key you must set the public $incrementing property on your model to false. If your primary key is not an integer, you should set the protected $keyType property on your model to string.
If you don't want to make id fillable, than you can use next instead of Point::create($value):
$point = Point::make($value);
$point->id = $value['id'];
$point->save();
Also you can Point::unguard() to temporarily disregard the fillable status of fields and make id temporary fillable.

MySQL set AUTO_INCREMENT value to MAX(id) + 1 shortcut?

I constantly need to "reset" the AUTO_INCREMENT value of my tables, after I delete a part of my rows. Let me explain with an actual example :
I have a table called CLIENT. Let us say before removing some rows, the auto_increment was set to 11. Then I delete the 4 lasts rows. The auto_increment is still set to 11. So when I will insert some clients again, it will make a hole of id.
I always need to "clean" the auto_increment, e.g. using this function below :
function cleanAutoIncrement($tableName, $columnAutoIncrement, $pdo)
{
$r = false;
try {
$p = $pdo->prepare("SELECT IFNULL(MAX($columnAutoIncrement) + 1, 1) AS 'max' FROM $tableName LIMIT 1;");
$p->execute();
$max = $p->fetch(PDO::FETCH_ASSOC)['max'];
$p = $pdo->prepare("ALTER TABLE $tableName AUTO_INCREMENT = $max;"):
$p->execute();
$r = true;
}
catch(Exception $e) {
$r = false;
}
return $r;
}
What the function do is to get the maximum id in the table, then increments it of 1, and return its value (if there was no rows in table, it return 1). Then I alter the table to reset a "clean" id in order not to let any hole of id.
QUESTION
Is there any MySQL command to perform this task without having to do this manually ?
To close this question, no shortcut exists in MySQL and it is not recommended to perform this task.

Insert into table if two keys do not exist

I have a table that maps itemId(item.id) and tagId(tag.id).
I'm writing a query that needs to insert a new row, but only if BOTH itemId and tagId do not already have an entry. What's the best way to do this?
Here is my current query that doesn't already check for an existing match:
// create tag-item maps
$sql = 'INSERT INTO item_tag
SELECT :itemId AS iid, tag.id AS tid
FROM tag
WHERE tag.name=:name';
try{
$stmt = $db->dbh->prepare($sql);
for($i = 0; $i < $count; $i++) {
$data = array(':itemId' => $itemId, ':name' => $tags[$i]);
$result = $stmt->execute($data);
if($result !== false) {
// Do nothing
}else {
return false;
}
}
return true;
}catch(PDOException $e) {
logit($e->getMessage());
return false;
}
A UNIQUE constraint would be the ideal solution, and according to the docs the MyISAM engine supports them.
ALTER TABLE item_tag ADD CONSTRAINT item_tag_iid_tid_uq UNIQUE (iid, tid);
Then if your INSERT tries to add a duplicate (iid, tid) pair it will throw and you can handle it in your catch code.
If you don't want to do the UNIQUE constraint, you could instead add an "existence" check to your INSERT query:
INSERT INTO item_tag
SELECT :itemId AS iid, tag.id AS tid
FROM tag
WHERE tag.name=:name' AND NOT EXISTS (
SELECT * FROM item_tag WHERE iid=:itemId AND tid=tag.id)
I tested this using my own differently-named tables, so hopefully I "translated" it correctly to your table/column names.

How to read row by row data from table like SQLReader using LINQ

May anybody tell me how to replace this code using Linq ?
using using Microsoft.Practices.EnterpriseLibrary.Data;
Public IDataReader GetRowByRowData()
{
Database Db = DatabaseFactory.CreateDatabase();
string sqlString = "SELECT * FROM TableTest";
DbCommand DbCmd = PpwDb.GetSqlStringCommand(sqlString);
Db .ExecuteReader(DbCmd);
}
Please help to get row by row data from table TableTest using Linq
you can do that like this:
var myQyery=from a in dataContext.Mytable
select a;
foreach(var item in myQuery)
{
//what you like
}
var records = (from p in context.TableTest
select p).ToList();
foreach(var record in records) {
// loop through each record here
}
ToList method will query the database and get the result set.
I load the primary key from my table into a list. Depending on the size of the data set and the primary key, loading into a list does not take too long. After loading the keys, use FirstOrDefault() with a where clause like so:
var keys = Db.TableTest.Select(x => x.primaryKey).ToList();
foreach (var k in keys)
{
var record = (from i in Db.TableTest
where i.primaryKey == k
select new
{
//Select only the columns you need to conserve memory
col1 = i.col1,
col2 = i.col2
}).FirstOrDefault();
//Process the record
}

Insert exception when using linqtosql

When I want to Insert data in my table this Exception appeared
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Message_Subject". The conflict occurred in database "C:\DOCUMENTS AND SETTINGS\TEHRANI\DESKTOP\MESSAGEADMINPAGE\APP_DATA\ASPNETDB.MDF", table "dbo.Subject", column 'ID_Subject'.
The statement has been terminated.
This Code for Insert :
string[] a = UserIDtxt.Text.Split(',');
foreach (String b in a)
{
Message M = new Message();
Guid i = (from q in MDB.aspnet_Memberships
where q.aspnet_User.UserName.ToString() == b.ToString()
select q).Single().UserId;
M.ID_Receiev = i;
M.ID_Message = Guid.NewGuid();
M.ID_Sender = (Guid)Admin.ProviderUserKey;
M.ID_Message_Parent = Guid.Empty;
if (SubjectDDL.SelectedItem.ToString() != "Other")
{
M.ID_Subject = new Guid(SubjectDDL.SelectedValue);
}
else
{
M.Other_Subject = Othertxt.Text;
}
M.Body = TEXTtxt.Text;
M.Date = DateTime.Now;
M.IsFinished = false;
M.IsRead = false;
MDB.Messages.InsertOnSubmit(M);
}
MDB.SubmitChanges();
you must set value all of feild
if (SubjectDDL.SelectedItem.ToString() != "Other")
{
M.ID_Subject = new Guid(SubjectDDL.SelectedValue);
M.Other_Subject = null;
}
else
{
M.ID_Subject = new Guid(SubjectDDL.SelectedValue);
M.Other_Subject = Othertxt.Text;
}
For what I can tell, based in the FOREIGN KEY constraint "FK_Message_Subject", you also have a table to Subjects. If this assumption is correct, when you assign M.ID_Subject a new Guid, it might not exist as a FOREIGN KEY in the Subjects table. You must find any existing Subject with the SubjectDDL.SelectedValue and retrieve the existing ID for the FOREIGN KEY. If it doesn't exist, create a new Subject and assign it directly to the Message M.
The same applies to when SubjectDDL.SelectedItem.ToString() == "Other". In this case, the FOREIGN KEY is null and it might be causing this error also.