How can I execute a script in a rule and pass a value back to a rule in booggie 2? - booggie

In booggie 2, how can I execute a script (programmed in Python) out of a rule and pass the script's return value to the rule?
Please note: The booggie-project does not exist anymore but led to the development of Soley Studio which covers the same functionality.

exec is the command to execute rules and scripts out of a rule. It is followed by parentheses containing a sequence composed of rules and scripts.
There is a strict order in which the application sequence in a rule is executed, (cf. Is there a fixed order of how the right-hand side of a rule is executed in GrGen.NET?). exec is always the last statements that's executed (before return of course). Hence, we can't pass a variable from exec to eval. Therefore, variables resulting from the execution of scripts in exechave to assigned to node/edge-attributes within the exec statement. To do so, we use curly brackets and write the same code as we would in an eval statement.
In the following example, a script is called that returns the highest value of three given values (a.value, b.value, c.value) and stores it a node's attribute (d.value).
exec ((max_value) = getMaxValue(a.value, b.value, c.value) ;>
{
d.value = max_value;
}
);

Related

Oracle SQL if statement based on parameter passed in via .sh script

I have a shell script which calls some SQL like so
sqlplus system/$password#$instance #./oracle/mysqlfile.sql $var1 $var2 $var3
Then in mysqlfile.sql, I define properties like this:
DEFINE var1=&1
DEFINE var2=&3
DEFINE var3=&3
Later in the file, I call another SQL script:
// i wish to wrap this in a if statement - pseudo-code
if(var3="true") do the following
#./oracle/myOthersqlfile.sql &&varA &&varB
I am not sure how to implement this though, any suggestions appreciated
You could (ab)use substitution variables:
set termout off
column var3_path new_value var3_path
select case
when '&var3' = 'true' then './oracle/myOthersqlfile.sql &&varA &&varB'
else '/dev/null'
end as var3_path
from dual;
set termout on
#&var3_path
The query between the set termout commands - which just hide the output of the query - uses a case expression to pick either your real file path or a dummy file; I've used /dev/null, but you could have a 'no-op' file of your own that does nothing if that's clearer. The query gives the result of that the alias var3_path. The new_value line before it turns that into a substitution variable. The # then expands that variable.
So if var3 is 'true' then that runs:
#./oracle/myOthersqlfile.sql &&varA &&varB
(or, actually, with the varA and varB variables already replaced with their actual values) and if it is false it runs:
#/dev/null
which does nothing, silently.
You can set verify on around that code to see when and where substitution is happening.
You can't implement procedural logic into sqlplus. You have these options :
Implement the IF-THEN-ELSE logic inside the shell script that is running the sqlplus.
Use PL/SQL, but then your SQL Script should be called as a process inside an anonymous block, not like an external script.
In your case the easiest way is to change your shell script.
#/bin/bash
#
# load environment Oracle variables
sqlplus system/$password#$instance #./oracle/mysqlfile.sql $var1 $var2 $var3
# if then
if [ $var3 == "true" ]
then
sqlplus system/$password#$instance #./oracle/myOthersqlfile.sql
fi
You should realise that sqlplus is just a CLI ( Command Line Interface ). So you can't apply procedural logic to it.
I have no idea what you do in those sql scripts ( running DMLs, creating files, etc ), but the best approach would be to convert them to PL/SQL, then you can apply whatever logic you need to.

TIBScript and local variables

I am working with Delphi 7 and Firebird 2.0. In my application I am using TIBScript components. The problem arises when I use local variables in the script. Firebird requires the names of local variables to be preceded by a colon in some cases. That’s where the problem lies in. The application stops showing the error message:
Dynamic SQL Error
SQL error code = -104
Token unknown - line 4, column 66
?
The token in question is the colon. Here is how my script looks like:
SET TERM ^ ;
EXECUTE BLOCK AS
DECLARE test_variable INT;
BEGIN
SELECT tt.id FROM test_table tt WHERE tt.name LIKE 'abc%' INTO :test_variable;
INSERT INTO test_table2(id, test_column)
VALUES(1, :test_variable);
INSERT INTO test_table3(id, test_column)
VALUES(1, :test_variable);
...
END^
SET TERM ; ^
The same script executes without any errors when run from IBExpert.
How can I use local variables in a TIBScript? Any help would be appreciated!
I want to add that this problem occurs only with variables inside an EXECUTE BLOCK construct. There is no problem with local variables in stored procedure and trigger definitions.
After executing the method TIBSQL.PreprocessSQL (Unit IBX.IBSQL line 2362), parameters marked with ":" on the front are replaced by "?". So you should use parameters without ":". Also I think it should be removed SET TERM. Instead, to set terminator value use the IBScript.Terminator property.
P.S. I watched unit IBX.IBSQL in Delphi 10.3 Rio.
this
EXECUTE BLOCK AS
DECLARE test_variable INT;
BEGIN
SELECT tt.id FROM USERS tt WHERE (tt.fname LIKE 'abc%') INTO test_variable;
END;
is executed properly when
IBScript.Terminator = ^;
Edit:
You can't execute INSERT with parameters in EXECUTE BLOCK using TIBScript component.
As Mark Rotteveel comented:
Unfortunately removing the colon is only an option in the into clause
in not with other occurrences of local variables or parameters.

How to ignore responding to stored '&lt' and '&gt' text in Oracle SQL statement?

I have an issue when writing the sql query below in SQL Command line. It asks me "Enter a value for lt:" and then gives error
ORA-00933: SQL command not properly ended
I need to properly read the column that includes '&lt' or '&gt' as a string. How can I edit the query to make it works?
Delete from authorization1
where role = 'staff' AND object = ' /department/gradstudent/gpa'
AND predicate = ' & l t ; 2.0') AND action = 'read'
Assuming you are using SQL*Plus or SQL Developer as your front end, this issue is that &foo is the syntax for defining substitution variables. You can
set define off;
before running your script to disable substitution variables. That will stop the front end from prompting you for a value.

SQLPlus is trying to drop package twice

While executing scripts in SQLPlus I've encountered a problem:
script.sql contains the following lines
#some_pkg.pks
#some_pkg.pkb
drop package some_pkg;
/
After calling
> sqlplus user/password#dbname #script.sql
the following messages are in console:
Package created.
Package body created.
Package dropped.
drop package some_pkg;
*
ERROR at line 1:
ORA-04043: object SOME_PKG does not exist
Please, explain what's happening here. Looks like the package is being dropped twice. Is it possible to avoid the error?
The rules of SQLplus command execution basically are:
Execute the current text when you encounter a semi-colon. Thus if a line doesn't end with a semi-colon, the current text continues to be collected.
If you encounter DECLARE or BEGIN, collect all the text and do not execute on semi-colons
If you encounter a slash (/), execute the collected text.
So what happens in your cases is, that both the semi-colon and the slash execute the DROP statements.
To fix it, remove the slash.
You only need the slash if you have a block of PL/SQL, which always with an END statement. Use semicolons for everything else.
Note: the above rules are simplified. It's more complex in practice.
Some examples will help to understand rules:
Below code will be executed once
begin
dbms_output.put_line('executed');
end;
/
Below code will not execute (missing semicolon)
begin
dbms_output.put_line('executed')
end
/
Below code will be executed twice
begin
dbms_output.put_line('executed');
end;
/
/
Below code will be executed once
select 1 from dual
/
Below code will be executed once
select 1 from dual;
Below code will be executed twice
select 1 from dual;
/

RULE with multiple commands

I can't figure out how to specify multiple commands for a rule.
According to the documentation, the syntax for creating a rule is:
CREATE [ OR REPLACE ] RULE name AS ON event
TO table [ WHERE condition ]
DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }
As per this definition, I have tried to create the following rule:
CREATE TABLE "test" (
"b" boolean NULL
);
-
CREATE OR REPLACE RULE test AS
ON UPDATE TO test DO INSTEAD
(
INSERT INTO test (b) SELECT FALSE;
INSERT INTO test (b) SELECT FALSE;
)
However, what happens is very weird - this query fails to parse the first insert complaining about syntax error at end of input LINE 4: INSERT INTO test (b) SELECT FALSE, but at the same time executes the rest of the query, therefore incorrectly creating a rule with just one insert command.
Notes: My version is 9.0 and I have not found a single example of a multi-command rule anywhere.
So, how do I correctly define multiple commands for a rule? Is it even possible?
As per comments, the problem lies in the database management tool I used - Adminer.
It somehow slices/corrupts the query, so you cannot create more than one command in a rule.
Note that this bug is present even in the (as of now) latest version 3.7.1.
Thanks a_horse_with_no_name for helping me resolve this issue.