Delphi Dbgrid delete a record - database

I have a multiple tabsheet. Each tabsheet in my PageControl that contain an Dbgrid with some button to manipulate this dbgrid.
Sometimes, when i click on button remove, my DBGrid not change. After delete, i see my value in my DBgrid.
If MyTable.recordcount > 0 then
begin
str := 'Value of name field/**' + MyTable.FieldByName('Name').AsString+'**/';
If Application.MessageBox(PChar(str), PChar('NAME'), MB_OKCANCEL + MB_ICONQUESTION) = IDOK then
begin
MyTable.Delete;
end;
end;
I try to add
MyTable.Refresh;
after delete but it doesn't work.
The value of myfield in the MessageBox is correct!
This problem appear when i select another Tabsheet in MyDBgrid.
It can be problem of focus in my DBGrid? It can be problem of state of my DBGrid(dsBrowser, dsEdit,...)?
=========================================================
I try to create a log for BeforeDelete event and AfterDelete event :
Log(1,'------------------------------------Before Del');
Log(1,Format('DataSet.IsEmpty:%s',[BoolToStr1(DataSet.IsEmpty)]));
Log(1,Format('DataSet.State:%d',[Ord(DataSet.State)]));
Log(1,'--------');
Log(1,Format('DataSet.RecNo:%d',[DataSet.RecNo]));
Log(1,Format('DataSet.TabSheet:%s',[DataSet.FieldByName('TabSheetName').AsString]));
Log(1,Format('DataSet.FieldName:%s',[DataSet.FieldByName('FieldName').AsString]));
Log(1,Format('DataSet.FieldId:%s',[DataSet.FieldByName('FieldId').AsString]));
on AfterDelete event :
Log(1,'------------------------------------After Del');
Log(1,Format('DataSet.IsEmpty:%s',[BoolToStr1(DataSet.IsEmpty)]));
Log(1,Format('DataSet.State:%d',[Ord(DataSet.State)]));
Log(1,'--------');
Log(1,Format('DataSet.RecNo:%d',[DataSet.RecNo]));
Log(1,Format('DataSet.TabSheet:%s',[DataSet.FieldByName('TabSheetName').AsString]));
Log(1,Format('DataSet.FieldName:%s',[DataSet.FieldByName('FieldName').AsString]));
Log(1,Format('DataSet.FieldId:%s',[DataSet.FieldByName('FieldId').AsString]));
I use the tabsheet as :
enter image description here
I obtain this log
------------------------------------Before Del
DataSet.IsEmpty:False
DataSet.State:1
--------
DataSet.RecNo:7
DataSet.TabSheet:tabsheet_0
DataSet.FieldName:
DataSet.FieldId:03
------------------------------------After Del
DataSet.IsEmpty:False
DataSet.State:1
--------
DataSet.RecNo:6
DataSet.TabSheet:tabsheet_0
DataSet.FieldName:
DataSet.FieldId:03
You can see in my log: the dataset not change (filedname and fieldId not change / the RecNo properties is change ) after delete the row that contain 03.

Since your problem is intermittent, you'll have to debug it yourself, because readers can't do that for you.
The first thing to do is to set up a logging function and call it in the dataset's BeforeDelete and AfterDelete events. You should record in it the identity of the current dataset row, the dataset's state (dsBrowse, dsEdit, etc) and anything other you think might be relevant (e.g. the identity of the active tabsheet) and see if you can spot in what circumstances the Delete fails. You could write the results of your logging calls to a TMemo on your form.
Ime, it's good practice only to allow a Delete if the dataset is in dsBrowse state.
By the way, I assume you are aware that a Delete operation is automatically aborted if the dataset is in dsInsert or dsSetKey state? From what you've described, I'd start debugging by investigating whether it's in dsInsert state when your problem arises. Of course, you can catch when the dataset is being put into dsInsert state by catching its BeforeInsert event and calling your logging function from there.

Related

How to update some data in SQL server into null for Classic ASP

I want to make update function in a web based system using Classic ASP to enable the user to cancel their application. I'm not using delete function because some data should be maintained, and some data will be set into NULL. This function also allow the user to choose date range in a form to delete their application.
There is no error shown but the set of data is not updated when click on cancel button in the form.
This is the code :
<%param="keyid=" & session("keyid")
idkehadiran=request("idkehadiran")
nokpl=request("nokpl")
set SimpanRS=server.CreateObject("adodb.recordset")
sql="select * from tms_kehadiran where nokpl='"&nokpl&"' and (tarikh >= '"&tarikh&"' and tarikh <= '"&hinggaTarikh&"')"
SimpanRS.open sql,connehr,3,3
while not SimpanRS.EOF
SimpanRS("alasan")=""
SimpanRS("nokpPenyelia")=""
SimpanRS("kelulusan")=null
if isnull(SimpanRS("datecreated")) then
SimpanRS("datecreated")=now
end if
SimpanRS("lastupdate")=now
SimpanRS.update
SimpanRS.movenext
wend
SimpanRS.close
set SimpanRS=nothing
%>
I don't what are the error with this code. Can anyone help me ?
Instead of looping the RS. You should use GetRows().
After that you can update the data in the SQL server while looping the array.

viewcriteria is not working for data having word "and"

i am working with applying view criteria programaticlly, till now it was fine, but when i searched with "develop and unit test" it is showing 0 records even though my table having data. iam using like operator. could any one help on this .
i have one table, having option to filter by providing select combo box list of vales, for every column when i select any thing in lov in value change listener i am applying viewcriteria programatically on table vo.
note. every thing is programatic view object only there is no point of entity, or sql
Sample Code:
DCIteratorBinding bindIterator = ADFUtils.findIterator("Tri2EWS_ETKAPIData_VO1Iterator");//Table viewObject(programatic)
Tri2EWS_ETKAPIData_VOImpl voimpl = (Tri2EWS_ETKAPIData_VOImpl) bindIterator.getViewObject();
ViewCriteria viewCriteria = voimpl.createViewCriteria();
viewCriteria.setName("MyVc");
ViewCriteriaRow viewCriteriaRow = viewCriteria.createViewCriteriaRow();
viewCriteriaRow.setOperator("ViewAttr1", "LIKE");
viewCriteriaRow.setAttribute("ViewAttr1", "stack and OverFlow");
viewCriteria.add(viewCriteriaRow);
viewCriteria.setCriteriaMode(ViewCriteria.CRITERIA_MODE_CACHE);
voimpl.applyViewCriteria(viewCriteria, true);
voimpl.executeQuery();
voipmpl.getRowCount();//Getting 0 here (Actually i should get 1)
Turn on debug messages for ADF BC (jbo.debugoutput) so you can see the SQL that is being generated.
This will help you figure out if the query is correctly formatted.

Delphi : incorrect parameter message error with AdoQuery using SQL aggregate function

I use delphi XE5, I have a database with 7 tables, and my problem: I click on a button which runs this code:
dbgridappr2.Enabled:=false;
adoquery4.Parameters.Clear;
datasource6.DataSet:=adoquery4;
ADOQuery4:=TADOQuery.Create(Application);
adoquery4.Active:=False;
adoquery4.Connection:=ADOConnection1;
adoquery4.SQL.Clear;
adoquery4.SQL.Add('select SPEC.ISp AS ''Spécialité'',COUNT(APPR.NValAp) AS ''Nombre dApprentis de même Spécialité'' ');
adoquery4.SQL.Add('FROM APPR,SPEC ');
adoquery4.SQL.Add('where SPEC.CSp=APPR.CSp ');
adoquery4.SQL.Add('GROUP BY SPEC.ISp ');
adoquery4.SQL.Add('ORDER BY COUNT(APPR.NValAp) desc ');
ADOQuery4.Prepared := True;
ADOQuery4.ExecSQL;
//adoquery4.Open;
adoquery4.Active:=true;
dbgridappr2.Visible:=true;
dbgridappr2.DataSource:=datasource6;
dbgridappr2.Enabled:=true;
I have the result in a DbGrid but the message error show incorrect parameter ??
I changed the button code but I always get the same error message. I have 10 buttons that all run similar code with different AdoQuery and I have the result but I have always the same message error
The code you've posted is an absolute mess. Here's why:
You clear the adoquery4.Parameters here, and assign adoquery4 to datasource6.DataSet:
dbgridappr2.Enabled:=false;
adoquery4.Parameters.Clear;
datasource6.DataSet:=adoquery4;
You then immediately throw away the existing adoquery4 (leaking memory in the process), and replace it with a new instance of TADOQuery:
ADOQuery4:=TADOQuery.Create(Application);
You then close the newly created ADOQuery4 (which could not possibly be Active at this point), assign a connection (which would be fine), and clear the SQL (which could not possibly have any content here):
adoquery4.Active:=False;
adoquery4.Connection:=ADOConnection1;
adoquery4.SQL.Clear;
So far, about 90% of what you've done is meaningless.
Then you make the mistake of calling ADOQuery4.ExecSQL;, which is used to execute queries that return no rowset, like INSERT, DELETE, and so forth. You need to use ADOQuery4.Open or ADOQuery4.Active := True instead for a SELECT. This is the actual cause of the error you're getting; you're calling ExecSQL with an SQL statement that returns a rowset, and that's invalid.
Let's try again, and throw in a slight improvement in the SQL in the process. Ignore everything you've posted here, and start over:
ADOQuery4.DisableControls;
try
// If the query is
if ADOQuery4.Active then
ADOQuery4.Close;
ADOQuery4.Parameters.Clear;
ADOQuery4.SQL.Clear;
AdoQuery4.SQL.Add('select SPEC.ISp AS ''Spécialité'',');
AdoQuery4.SQL.Add('COUNT(APPR.NValAp) AS ''Nombre dApprentis de même Spécialité''');
AdoQuery4.SQL.Add('FROM APPR INNER JOIN SPEC');
AdoQuery4.SQL.Add('ON SPEC.CSp = APPR.CSp');
AdoQuery4.SQL.Add('GROUP BY SPEC.ISp ');
AdoQuery4.SQL.Add('ORDER BY COUNT(APPR.NValAp) desc');
ADOQuery4.Open;
finally
ADOQuery4.EnableControls;
end;
(I don't know what all of the juggling of the dbgridappr2.DataSource is about, but unless you're changing the datasource from a different query none of that is necessary. The calls to DisableControls and EnableControls stops any UI components from being updated while the new query is executed.)

TableAdapter.Update Does Not Save Imported Row

I've hit a problem with my database. The purpose of the section of my application is simple this; when a user marks an assignment of work complete, it will transfer one DataRow from "activeUnits" by using the "table.ImportRow" method to another table called "completedUnits" and then use the table adapter to update this change to the core database. However when testing this function the Dataset has completed the move of rows successfully internally, but upon using the TableAdapter.Update method the update of data to the database returns simply as "0" with no changes made or errors to lead.
Try
Dim activeRowMove As DataRow = Me.AssignmentDataSet.activeUnits.Rows(currentIndex)
Dim newMove As DataTable = Me.AssignmentDataSet.completedUnits
newMove.ImportRow(activeRowMove)
'UPDATE CHANGES
Me.Validate()
CompletedUnitsBindingSource.EndEdit()
Console.WriteLine(Me.CompletedUnitsTableAdapter.Update(Me.AssignmentDataSet.completedUnits))
activeUnitsTitle.Text = ("Assignment Completed!")
Catch ex As Exception
Console.WriteLine("Failed to update new table: " & ex.ToString)
activeUnitsTitle.Text = ("Failed to save!")
End Try
Is there somewhere in my code which I've simply done wrong, or any better or efficient way of moving a datarow is appreciated!
My database is not copied in my project's bin folder and every update goes to one central location.
If needed the following link is two screenshots of my current layout and data - here.
From MSDN:
Calling ImportRow preserves the existing DataRowState along with other values in the row
So, if the DataRowState in your "from" table is Unchanged, then its state will remained Unchanged in the "to" table, and it will not get saved.
Make sure to change the DataRowState of the newly imported row to Added
Cheers

Salesforce Apex error: SELF_REFERENCE_FROM_TRIGGER

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger triggerOpportunityCloseInstallDateChange caused an unexpected exception, contact your administrator: triggerOpportunityCloseInstallDateChange: execution of BeforeUpdate caused by: System.DmlException: Delete failed. First exception on row 0 with id 00o30000003ySNhAAM; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 0063000000i23T9) is currently in trigger triggerOpportunityCloseInstallDateChange, therefore it cannot recursively update itself: []: Class.OpportunitySchedule.BuildScheduleAndUpdateDates: line 17, column 5
I'm getting the above error when I try to excute the code below.
I have a trigger on the "before" of an opportunity. It then calls the below class with trigger.new.
public with sharing class OpportunitySchedule {
public static void BuildScheduleAndUpdateDates(List<Opportunity> OpportunityList) {
for (Integer i = 0; i < OpportunityList.size(); i++)
{
Opportunity opp_new = OpportunityList[i];
List<OpportunityLineItem> lineItems = [Select o.Id, (Select OpportunityLineItemId From OpportunityLineItemSchedules), o.System_Add_on__c, o.ServiceDate, o.Schedule_Length__c , o.Monthly_Quantity__c, o.Monthly_Amount__c
From OpportunityLineItem o
where o.Opportunity.Id = :opp_new.Id];
for (OpportunityLineItem item : lineItems)
{
item.ServiceDate = opp_new.CloseDate;
update item;
delete item.OpportunityLineItemSchedules;
}
}
}
}
I'm trying to delete all of the Opportunity Line Item Schedules when someone edits an opportunity. The weird thing is, I can remove the delete item.OpportunityLineItemSchedules line and the code runs, it will update the item. I don't understand why deleting a childs children (Opportunity -> OpportunityLineItem -> OpportunityLineItemSchedule) would cause a recursive loop.
I've tried implimenting the below code in this link with no luck:
http://boards.developerforce.com/t5/Apex-Code-Development/Trigger-is-fired-twice-due-to-the-workflow...
I've also commented out all other triggers to make sure one of them aren't causing it.
Does anyone know what I'm doing wrong?
A few things I noticed. First, never put DML inside a loop and especially when inside of a trigger. Reading up on Bulkified triggers here would help: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_triggers.htm
In your code you're almost there. Instead of doing your update in the loop, simply update your entire list after the loop:
for (OpportunityLineItem item : lineItems)
{
item.ServiceDate = opp_new.CloseDate;
//update item;
//delete item.OpportunityLineItemSchedules;
}
update lineItems;
Then you would make a new list of just OpportunityLineItemSchedules that had ParentId == OpportunityLineItem.Id. Then you would delete that entire list in one call:
delete saidList;
As for the recursion, in a master-detail relationship Force.com will handle the deletion of children automatically. Not so in a lookup, where you need to delete these by hand. Though I'm uncertain about OpportunityLineItemSchedules specifically, I'd try either starting things with using an AFTER trigger, or use a helper class that your trigger thread keeps in memory to ensure that once inside of your trigger handler class, that it doesn't enter it again.
Unfortunately the above is all I had a moment to share! Good luck and welcome to Force.com programming. Hope it grows on you.
I don't understand why deleting a childs children (Opportunity -> OpportunityLineItem -> OpportunityLineItemSchedule) would cause a recursive loop.
When using revenue schedules the TotalPrice on the parent OpportunityLineItem is updated based on the associated OpportunityLineItemSchedules. So when you delete the OpportunityLineItemSchedule records you are effectively updating the OpportunityLineItem, which causes the SELF_REFERENCE_FROM_TRIGGER DML Exception.
See the Effects on Opportunities and Opportunity Line Items section of the OpportunityLineItemSchedule documentation.
Deleting an OpportunityLineItemSchedule has a similar effect on the related OpportunityLineItem and Opportunity. Deleting an OpportunityLineItemSchedule decrements the OpportunityLineItem TotalPrice by the deleted OpportunityLineItemSchedule Quantity or Revenue amount. The Opportunity Amount is also decremented by the OpportunityLineItemSchedule Quantity or Revenue amount, and the Opportunity ExpectedRevenue is reduced by OpportunityLineItemSchedule Quantity or Revenue amount multiplied by the Opportunity Probability.

Resources