Function list not appearing in BI Publisher when adding event triggers - bi-publisher

I'm trying to create an after-report trigger for my data model. I created the following package on my database:
Package:
create or replace PACKAGE CM_BILL_PRINT_PACKAGE AS
P_TO_ACCT_ID CI_ACCT.ACCT_ID%TYPE;
P_FROM_ACCT_ID CI_ACCT.ACCT_ID%TYPE;
P_BATCH_NBR CI_BILL_ROUTING.BATCH_NBR%TYPE;
P_BATCH_CD CI_BATCH_CTRL.BATCH_CD%TYPE;
P_LARGE_SW CHAR(1);
FUNCTION afterreport RETURN NUMBER;
END CM_BILL_PRINT_PACKAGE;
Package Body:
create or replace PACKAGE BODY CM_BILL_PRINT_PACKAGE AS
v_result NUMBER;
FUNCTION afterreport RETURN NUMBER AS
BEGIN
SELECT 1 INTO v_result FROM DUAL;
RETURN (v_result);
END afterreport;
END CM_BILL_PRINT_PACKAGE;
Afterwards I created provided the package name as my default DB package on the data model properties.
Oracle DB Default Package
Then proceeded to create the event trigger. However, the function I created does not appear on the list.
Available Functions
Any ideas on what I'm missing?

The RETURN type of Function should be of BOOLEAN type.
It will work.

Related

Snowflake / How get the original caller when a stored procedure is executed as OWNER

I have created a stored procedure with the behavior execute as OWNER (I need the owner’s rights).
I am looking to get the original role of the user that called it, is there any way to do that?
Unfortunately, as expected the select current_role() statement returns the owner's role ...
If a workaround exists, I would appreciate if you could describe it to me.
Following Mike's advice:there the code I done to test Harsh's solution:
Failed again ^^
There's my code. May be you ll see my mistake.
create or replace procedure do_noting_proc()
returns string
language javascript
execute as OWNER
AS
$$
var retour="Resultat";
try{
rs0=snowflake.createStatement({sqlText:"SELECT $QUERY_TAG;"}).execute();
cR=rs0.getColumnValue(1);
return "QRValue= "+callerRole;
}catch(err){
return "do_noting_proc KO: "+ err.message+";";
}
$$;
create or replace procedure test_proc()
returns string
language javascript
execute as CALLER
AS
$$
var rString="Result -->";
try{
rs0=snowflake.createStatement({sqlText:"SELECT CURRENT_ROLE();"}).execute();
rs0.next();
cr="testQT"+rs0.getColumnValue(1);
snowflake.createStatement({sqlText:"alter session set QUERY_TAG="+cr+";"}).execute();
rs=snowflake.createStatement({sqlText:"call PUBLIC.do_noting_proc();"}).execute();
rs.next();
rString+=rs.getColumnValue(1);
}catch(err){
return "test_proc: "+ err.message+";";
}
return "test_proc : "+rString;
$$;
Thencall share_view_or_table();
==>test_proc : ** Result -->do_noting_proc KO: Use of session variable '$QUERY_TAG' is not allowed in owners rights stored procedure;**
(procedure created by sysadmin and Executed as sysadmin)
Also if I run 'code'
select $QUERY_TAG;
I get the error: SQL compilation error: error line 1 at position 7 Session variable '$QUERY_TAG' does not exist
whereas
SHOW PARAMETERs LIKE 'QUERY_TAG' IN SESSION ;
works fine and print TESTQTSYSADMIN
#Harsh many thanks for your time
When using EXECUTE AS OWNER the rules do not permit reading the caller's session details, including their identity or role:
Owner’s rights stored procedures adhere to the following rules within a session:
[…]
Cannot access most caller-specific information. For example:
Cannot view, set, or unset the caller’s session variables.
Can read only specific session parameters, and cannot set or unset any of the caller’s session parameters.
Cannot query INFORMATION_SCHEMA table functions, such as AUTOMATIC_CLUSTERING_HISTORY, that return results based on the current user.
While inconvenient, you can use logic within the stored procedure to enforce that the role name of the caller should be passed as an argument:
CREATE OR REPLACE PROCEDURE PROC(ROLE_NAME STRING)
[…]
var VALID_ROLES_ARRAY = ["FOO", "BAR"];
var IS_VALID_CALLER_ROLENAME = VALID_ROLES_ARRAY.includes(ROLE_NAME);
[…];
CALL PROC(CURRENT_ROLE());

How to use a temporary table with dynamic sql?

Im want to use a temporary table with dynamic sql but i have an error saying that the column Column, parameter, or variable #3: Cannot find data type MyTable. Must declare the table variable "#CountriesFound".
Here's my code
ALTER PROCEDURE sqlDynamic #countryId int
AS
CREATE TYPE MyTable AS TABLE ([countries] varchar(50));
DECLARE #statement NVARCHAR(MAX)
DECLARE #CountriesFound AS MyTable
INSERT INTO #CountriesFound(countries)
select Name
FROM CountriesFound
SET #statement =
'SELECT name, CASE WHEN (c.name IN (SELECT countries FROM #CountriesFound)) THEN 1
ELSE 0
END as countryFound FROM Country c WHERE c.countryId = #countryId'
EXECUTE sp_executesql #statement,
N'#countryId int, #CountriesFound MyTable READONLY',
#countryId = #countryId,
#CountriesFound=#CountriesFound;
Any idea how to fix it ?
The error you are getting has nothing to do with dynamic sql. You cannot create a stored procedure that uses a User-Defined DataType (MyTable in your example) in the same procedure that is going to create the TYPE. The TYPE has to already be created before the procedure will even let the code compile.
Consider this simplified code:
CREATE PROCEDURE TypeTest
AS
CREATE TYPE MyTable AS TABLE ([Id] int);
DECLARE #mt AS MyTable;
Just executing this will give the error:
Msg 2715, Level 16, State 3, Procedure TypeTest, Line 1 Column,
parameter, or variable #1: Cannot find data type MyTable. Parameter or
variable '#mt' has an invalid data type.
You need to CREATE the TYPE outside of the procedure code before you try to create the procedure. It doesn't make sense to CREATE a TYPE inside a procedure code, since TYPE objects are permanent on the server until they are dropped anyway, and procedures are usually created to be run multiple times.
It would be nice if the SQL Server gave an error message more to this effect, but SQL Server isn't famous for having the most helpful error messages.

"Snapping" sub-tables back into parent table in Lua

I'm making a library for a program with the ComputerCraft mod in Minecraft. The library is an archive library, which uses the table.serialize function in Lua to archive files. In each function, you can supply the folders (sub-tables) to use; e.g. add_folder(table, "new_folder", "folder1", "another_folder") adds new_folder to another_folder that is inside folder1. I have made a recursive function to get the table from a list of folders:
local function getFolder(table, ...) return getFolder(table[select(1, expand(arg))], expand(table.remove(table, 1))) end
This works well when I add the information, but the functions return a modified version of this sub-table, as shown in the add_folder function:
function add_folder(table, name, ...)
local folders = getFolder(table["data"], expand(arg))
folders[name] = {}
return folders --Returns incomplete table
end
I would like to "snap" this sub-table back into the parent so that the above function will return the whole table. How can I get this sub-table back into the parent?
Note that I can not use libraries that use C modules, as the ComputerCraft implementation of Lua is just an interpreter, and not designed to use compiled modules. Otherwise, I would totally use TAR.

Script always throws an error if CREATE/ALTER is not first statement

I am getting an error when I try to execute the script that is given at end of this post. My requirement is to check for procedure's existence, then drop it if it exists and finally create the procedure.
How would I do this using a single script file?
Procedure Proc_GenerateTestData. 'CREATE/ALTER PROCEDURE' must be the first statement in a query batch. SQL2.sql 12 1
The SQL script that always throws above error is as below.
IF OBJECT_ID('dbo.Proc_GenerateTestData', 'p') IS NOT NULL
BEGIN
DROP PROCEDURE dbo.Proc_GenerateTestData
END
CREATE PROCEDURE dbo.Proc_GenerateTestData #numberOfRecords INT = 100
AS
--drop table #temp1
DECLARE #currentTime AS TIME = CAST(GETDATE() AS TIME);
DECLARE #currentWorkShiftDate AS DATETIME = CAST(CAST(GETDATE() AS DATE) AS DATETIME);
DECLARE #startTime TIME,
#lastShiftStartTime TIME;
DECLARE #tenantId AS UNIQUEIDENTIFIER = (SELECT TOP (1)
Tenants.Id
FROM Tenants
ORDER BY Tenants.Id ASC);
DECLARE #workshiftId INT,
#lastShiftStartDate DATETIME;
--more statements for this procedure follow
As the error clearly says - the CREATE PROCEDURE must be the first statement in a query batch.
This is not the case here, since you have the check for the DROP before hand.
You need to change your script so that the CREATE PROCEDURE statement is really the first in the query batch. If you're running this in SQL Server Management Studio, just add a GO delimiter before the CREATE.

How to create "New" functions using Delphi XSD databinding wizard

According to Embarcadero's documentation
Call the generated New... function to create the TXMLDocument instance for an empty document when you want to create all the data in your application:
var
StockList: IXMLStockListType;
begin
StockList := Newstocklist;
_di_IStockListType StockList = NewStockListType();
However, I don't get any New... functions in the 26833 lines of code Delphi generated when importing the XSD for the Clinical Document Architecture .
So, what triggers the generation of these New functions?
If your XSD document contains multiple xs:element (or simpletype,complextype,...) nodes at the root level, the wizard can't determine what the root level element will eventually be of your xml document. In that case you must write the Newxxx statement yourself:
var yourType : IXMLYourType;
...
yourType := NewXMLDocument.GetDocBinding(
'<root level yourtype tagname>',
TXMLYourType,
'') as IXMLYourType;
Try to import an xml document that adheres to the xsd and you will see that the newxxx function will be generated.
UPDATE
If you check the documentElementType for the Type you want to use as root element, the new, load and get functions are created. If you don't do that you will get this warning:

Resources