Oracle Forms Execute_query giving FRM-40737 error - oracleforms

I am getting an error
FRM - 40737 - illegal restricted procedure GO_BLOCK in
WHEN-VALIDATE-RECORD trigger.
My Code is
IF event_name = 'WHEN-VALIDATE-RECORD'
THEN
IF (form_name = 'OEXOEORD' AND block_name = 'ORDER')
THEN
-- call procedure to validate and cascade the ship method code.
cascade_ship_method;
execute_query;
END IF;
What am I doing wrong here ?

This is because Oracle Forms has two types of built-in procedures - restricted and unrestricted. Some triggers enable restricted procedures, some not (see Oracle Forms help, every trigger has information which procedures it enables).
Trigger WHEN-VALIDATE-ITEM fires for example when user moves cursor from one record to the other (this is called navigation). In this case it leaves one record and enters other. There is fired following chain of triggers
WHEN-VALIDATE-ITEM
WHEN-VALIDATE-RECORD
POST-ITEM
POST-RECORD
PRE-RECORD
PRE-ITEM
If any of this trigger fails, navigation is canceled and cursor returns to the original item. If you call any procedure, which starts new navigation (like GO_BLOCK), Oracle Forms would not be able to manage first navigation.
This is, why some procedures are restricted.

It might be relevant with content of cascade_ship_method. When I got this error, I had missed an apostrophe in the SET_BLOCK_PROPERTY statement. When I fixed, it worked. This is the correct structure in my code block:
SET_BLOCK_PROPERTY (
'TABLE_A',
default_where,
'column_a= '
|| ''''
|| variable
|| '''');

Related

FDQuery Interface to Progress Bar - DELPHI

I am trying to make an interface for my insert Query, this moves a huge number of data.
DataModule2.FDQueryInsertExceed.Close;
DataModule2.FDQueryInsertExceed.Sql.Clear;
DataModule2.FDQueryInsertExceed.Sql.Add('INSERT IGNORE INTO tblLogs');
DataModule2.FDQueryInsertExceed.Sql.Add('SELECT * FROM tbllogs WHERE Datetimelog <
date_sub(NOW(), INTERVAL 1 month);');
DataModule2.FDQueryInsertExceed.ExecSQL;
Dont know where to put the progress bar, and also if you can post here a link with full manual of FD Components.
FireDAC includes the TFDEventAlerter, which allows applications to receive certain notifications
from the SQL backend, including some progress notifications. Unfortunately, it does not support
MySQL so you are going to have to devise a way of updating your ProgressBar yourself.
The main problem with doing it yourself is that after you call DataModule2.FDQueryInsertExceed.ExecSQL,
it will not return until ExecSQL has completed execution, so you can't get any opportunity
to update your ProgressBar until then and by the time that you do, the SQL backend has finished
working.
So, realistically, the best you can do is to snip your db inserted up into a series of batches and
update the ProgressBar after each one. Before you start the batches, you can do a SELECT COUNT(*)
which should tell you at least approximately how many rows will be involved overall, so that
you can calculate the percentage complete after each batch. I say "approximately"
in case new inserts are required while your ExecSQL is executing,
The simplest place to start is by determining how many of your inserts can be executed in
a few hundred milliseconds, parameterize your SQL to match that and use a TTimer to start
each batch. So your TTimers's OnTimeer wou look something like
TForm1.OnTimer1.OnTimer(Sender : TObject);
var
S : String;
begin
S := 'INSERT IGNORE INTO tblLogs SELECT * FROM tbllogs WHERE Datetimelog ... //
// complete as necessary to add a starting DateTime and an ending one for the batch
DataModule2.FDQueryInsertExceed.Sql.Text := S;
DataModule2.FDQueryInsertExceed.ExecSQL;
// Update ProgressBar here
end;
An enhancement (but a step change in difficulty) would be to call DataModule2.FDQueryInsertExceed.ExecSQL
in a background thread and, once it has executed, execute code in the main, VCL thread, not in the background thread, to update
the ProgressBar. However, exactly how to do that is way beyond the scope of this answer.

How to Insert data from datagridview Rows to mysql database in vb.net using stored procedure

Im stucked. I am trying to insert data from the grid to the database.But I'm stucked.
Slugsie's comment is pertinent, but needs to go a little further:
You're actually clearing the entire parameters collection before you call the procedure. If it were a house, you went to all the effort to build the whole thing, then at the last minute you demolish it and show the customer a cleared lot
Don't clear the Parameters collection at all. Add all the parameters to it OUTSIDE the loop, then inside the loop, set the values:
'general pattern
cmd.Parameters.AddWithValue("param1", "...")
cmd.Parameters.AddWithValue("param2", "...")
cmd.Parameters.AddWithValue("param3", "...")
cmd.Parameters.AddWithValue("param4", "...")
For Each something In somethingElse
cmd.Parameters("param1").Value = something.Whatever1
cmd.Parameters("param2").Value = something.Whatever2
cmd.Parameters("param3").Value = something.Whatever3
cmd.Parameters("param4").Value = something.Whatever4
cmd.Execute...
Next something
That's the pattern you should be adopting
Though jmc also makes a useful comment; you could make your life a lot easier by
adding a DataSet type file to your project
open it, right click the surface, choose Add TableAdapter
when configuring the wizard for the adapter, say you want to use stored procedures for your select, insert, update etc
wire the procedures up to the relevant table columns
Now in code you can save data just by a single line or two:
Dim t as New WhateverTableAdapter
t.Update(yourWhateverDatatable) 'the WhateverDataTable is bound to a grid, the user has edited the rows in it by changing the grid
That Update() call will perform any necessary use of the Insert/Update/Delete procedures depending on if the datarow in the table is an Added, Modified or Deleted state

Best way to create and manage someone's triggers (GAS)

I wrote some GAS code for a person and it required a trigger.
I created this line and asked the person to call it to set up his trigger (as it is his spreadsheet):
ScriptApp.newTrigger("myFunction").timeBased().everyDays(1).inTimezone("Australia/Brisbane").atHour(5).create()
But then, I cannot see his trigger.
To see if a trigger is there I used:
Logger.log(ScriptApp.getProjectTriggers())
It returned an empty array so looks like the trigger is gone but I don't see it physically...
So, if it's a client, it is not cool to ask his "please set up your trigger" and then not be able to see it and then ask to check if it's there.
What's the best way to set up and manage triggers for clients?
EDIT: As stated in the accepted answer, It seems other user's triggers are viewable manually in the dashboard.
Other user's triggers are not available for you to view programmatically/manually for security reasons.
I created this line and asked the person to call it to set up his trigger (as it is his spreadsheet):
You must explicitly create a menu , so that the user may click on it to create the trigger:
If the user sets up a trigger through menu options, You can set the id of trigger to properties service like this.
function createTrigger(){ //to be linked to a "Create Trigger" menu
// Creates an edit trigger for a spreadsheet identified by ID.
var tid = ScriptApp.newTrigger('myFunion')
.forSpreadsheet('1234567890abcdefghijklmnopqc3')
.onEdit()
.create()
.getUniqueId();
//set id of trigger in properties
PropertiesService
.getScriptProperties() //if you want public access to trigger(If not use getUserProperties)
.setProperty(
Session.getEffectiveUser().getEmail() ||
('user1 ' + Math.random().toFixed(3)),
tid
);
//Inform user: trigger created successfully.
SpreadsheetApp.getActive().toast('Trigger created successfully with id: ' + tid);
//#see https://script.google.com/home/triggers
}
To see his triggers, open the editor and choose "Current Project Triggers" from the Edit menu.
On the trigger page, click the "x" on the "Owned by me" filter. Then you shold see all the triggers for the project and know if it is set up. It won't tell you who owns it, I don't think.
You cannot "manage" his triggers from there, just see them. There is no way to mess with other peoples triggers (a much debated topic!) but you can change the name of the function to break a trigger.

MySQL trigger not working properly

I'm getting a strange error while trying to use a MySQL trigger.
I'm using XAMPP and creating the trigger using PhpMyAdmin.
The trigger's code is:
BEGIN
DECLARE stud INT(11) DEFAULT 0;
DECLARE sw CURSOR FOR
(SELECT CodiceStudente FROM Listastudenticorsi WHERE CodiceCorso = NEW.CodiceCorso);
OPEN sw;
get_loop: LOOP
FETCH sw INTO stud;
INSERT INTO inbox(Mittente, Destinatario, Oggetto, Contenuto, Data) VALUES (NEW.CodiceDocente, stud, "Nuova news inserita", NEW.Oggetto, NEW.Data);
END LOOP get_loop;
END
And is called BEFORE INSERT into the table 'News'.
What happens is that the syntax is correct, but when I try to run it triggering the event it says "#1329 - No data - zero rows fetched, selected, or processed".
I tried to find out what the real problem is, and it seems to be the line "FETCH sw INTO stud"; I tried many times and the SELECT statement DOES return the correct values, so 'sw' can't be empty... I'm stuck at this point.
There are 3 tables interested by this trigger. 'News' is the one that triggers the event; it has some columns that are called using the keyword "NEW". The second one is Inbox; it is the table in which I'll insert some values after the trigger has performed its actions. Finally, there's "Listastudenticorsi", which means approximately "list of students and courses".
What I do is: when a News is inserted, I get the course it refers to, its object, its date and the submitter of the news, I find (using the select statement) the students who attend the course that the News is referring to, and then send a mail to each of them using the insert statement.
You have no continue handler for the cursor, as I see it. It would allow that cursor to actually do something.
From the mysql Cursor manual page, see this.
Here too is a link to a stored proc I wrote showing a continue handler with a flag specifying done for the loop.

Lazarus, can't get DB Update working. How can I preview whats being submitted?

Hi I have a form setup using TMySQL51Connection, TSQLTransaction & TSQLQuery modules, it retrieves info from the DB without issue but I'm having problems with updates.
The DB is pretty large so I'm starting with just the 1st couple of rows, once they're working I'll extend the query.
My TSQLQuery.UpdateSQL is as follows
UPDATE table SET
ContactFirst = :ContactFirst,
ContactSur = :ContactSur
WHERE AccountID = :AccountID
Then I have a button in my form, the onCLick event contains:
begin
accSelect.Edit;
accSelect.Post;
accSelect.ApplyUpdates;
dbTransaction.CommitRetaining;
sqlbl1.Caption := accSelect.UpdateSQL;
end;
Clicking the buttons does precisely nothing with the DB, it generates no error messages, just updates the caption on sqlbl1. Is there anyway to preview what Lazarus is sending to the DB with values included so I can track down whats going wrong?
I tried adding a logging event to the SQLConnection but couldn't work out how to get it generating logs.
From my experience, the Edit, Post and ApplyUpdates methods are used in conjunction with a TClientDataSet. In that case you would simply assign new values to the fields in the CDS (after navigating to the record you want to Edit) then Post those changes (no need for an Update SQL statement). Something like this...
MyCDS.Edit;
MyCDS.FieldByName('ContactFirst').Value := sContactFirstName;
MyCDS.FieldByName('ContactSur').Value := sContactSurname;
MyCDS.Post;
MyCDS.ApplyUpdates;
Alternatively, you could use a Query component, write the UPDATE SQL into the SQL property, and use ExecSQL or whatever method has been implemented for that component (there are many database access components that each have their own idiosyncrasies)
Here's some code off the top of my head. Please excuse me but I'm not familiar with Lazarus specifics - it's basically Delphi code.
MySQLQuery.SQL.Clear;
MySQLQuery.SQL := 'UPDATE MyTable
SET ContactFirst = :ContactFirst,
ContactSur = :ContactSur
WHERE AccountID = :AccountID';
MySQLQuery.Params.ParamByName('ContactFirst').Value := sContactFirstName;
MySQLQuery.Params.ParamByName('ContactSur').Value := sContactSurname;
MySQLQuery.Params.ParamByName('AccountID').Value := iAccountID;
try
MySQLQuery.ExecSQL;
ShowMessage('Update succeeded');
except on e: Exception do
ShowMessage(e.Message);
end;
So it might be that you've ended up using half of both methods and neither of them completely.