How to create a stored procedure - Netezza Aginity - sql

I am creating a test stored procedure but it does not work for me. What am I doing wrong?
I am using Aginity Workbench for PureData System for Analytics
CREATE OR REPLACE PROCEDURE OID_DB.SP_TEST_1(CHARACTER VARYING(8))
RETURNS CHARACTER VARYING(ANY)
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
PV_YYYYMMDD ALIAS FOR $1;
BEGIN
RETURN 'TEST_OK';
END;
END_PROC;
ERROR [HY000] 'CREATE OR REPLACE PROCEDURE OID_DB.SP_TEST_1(CHARACTER VARYING(8)) RETURNS CHARACTER VARYING(ANY) LANGUAGE NZPLSQL AS BEGIN_PROC DECLARE PV_YYYYMMDD ALIAS FOR $1'
error > ^ found "" (at char 118) unterminated BEGIN_PROC string

I faced similar issue. Following solution worked for me:
Right click on the query window -> Options -> Change "Query Kind" from "Ordinary SQL" to "SP/Function".

Related

FireDAC could not handle parameter names longer than 30 chars

I use Oracle database version 19.3.0 and it can handle parameter names longer than 30 chars. If I execute in Delphi FireDAC-procedure "ExecProc" to call Stored Procedure in SQL, Delphi throws "ORA-01036 : illegal Variable name/number" exception and calling of the procedure terminates prematurely, because one parameter name is longer then 30 chars.
Is there some FireDAC property to change this behavior without changing parameters name length?
"C:\Program Files (x86)\Embarcadero\Studio\19.0\source\data\firedac\FireDAC.Phys.Oracle.pas"
Solution: Change pbByName to pbByNumber
procedure TForm5.Button1Click(Sender: TObject); begin
FDStoredProc1.ParamBindMode := pbByNumber;
FDStoredProc1.FetchOptions.Items := [fiBlobs, fiDetails]; //This disables automatic fetching of parameters from server
FDStoredProc1.Params.CreateParam(ftString,'Averylongparamternamethathopefullyislongerthanthirtycharacters',ptInput);
FDStoredProc1.params.CreateParam(ftString,'outparam',ptOutput);
FDStoredProc1.Params[0].AsString := 'Hello World';
FDStoredProc1.ExecProc;
ShowMessage(FDStoredProc1.Params[1].AsString);
end;

using psql environment in a function declaration

I am failing to use a parameter in function declaration.
a SQL script like :
CREATE OR REPLACE FUNCTION test_functon() RETURNS trigger AS
$BODY$
DECLARE
test int:=:SRID;
BEGIN
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
in a file.
And running psql -v SRID=2056 -f my_file.sql
leads to the error
ERROR: syntax error at or near ":"
This looks like the SQL is run without the var being properly replaced by its value.
What is the solution for this?
It seems like psql does not interpolate variables in the body of functions.
The following SQL verifies that.
SELECT :SRID;
CREATE OR REPLACE FUNCTION test_functon() RETURNS :TYPE AS
$BODY$
BEGIN
RETURN :SRID;
END;
$BODY$
LANGUAGE plpgsql;
Running that file results in this:
$ psql -v SRID=2056 -v TYPE=int -f query.sql
Expanded display is used automatically.
Null display is "ยค".
?column?
----------
2056
(1 row)
psql:query.sql:9: ERROR: syntax error at or near ":"
LINE 4: RETURN :SRID;
^
Notice how the return type defined by the variable TYPE is still interpolated, but everything inside the body is off limits.
You'll have to resort to a different mechanism to get your variable in there. You could leverage the fact that psql accepts a query through STDIN:
$ sed 's/:SRID/2056/' query.sql | psql

Db2: How to deploy an Oracle PL/SQL package in db2?

I tried to create an Oracle PL/SQL package in Db2, but ran into errors.
CREATE OR REPLACE PACKAGE ARITHMETIC AS
function add (
first number,
second number)
return number;
END ARITHMETIC;
CREATE OR REPLACE PACKAGE BODY ARITHMETIC AS
function add(
first number,
second number)
return number AS
BEGIN
return first + second;
END add;
END ARITHMETIC;
When I run the above code, it results in the following error:
Deploy [tnbdr]DB2INST1.ARITHMETIC Running
DB2INST1.ARITHMETIC - Deploy for debug started.
Create PL/SQL Package Specification returns SQLCODE: -104, SQLSTATE: 42601.
DB2INST1.ARITHMETIC: 1: An unexpected token "PACKAGE" was found
following "CREATE OR REPLACE ". Expected tokens may include:
"VIEW".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.18.60
An unexpected token "PACKAGE" was found following "CREATE OR REPLACE ". Expected tokens may include: "VIEW".. SQLCODE=-104,
SQLSTATE=42601, DRIVER=4.18.60
DB2INST1.ARITHMETIC - Deploy for debug failed.
DB2INST1.ARITHMETIC - Roll back completed successfully.
How can I deploy the package, why is it failing?
Db2 supports the compilation / creation of PL/SQL packages when the database is set up for Oracle compatibility:
db2set DB2_COMPATIBILITY_VECTOR=ORA
db2stop
db2start
Bit 12 in the DB2_COMPATIBILITY_VECTOR enables PL/SQL compilation.

Netezza Stored procedure DB_NAME as an argument

HI everyone I wrote a kind of a simple procedure in Aginity(Netezza). The stored procedure basically has to load data from one db.table1 to db2.table2. Simple right? Then then the procedure - procedure 1 takes in an argument, which is the name of the database(db).
This is the error message I get whenever I try to run my procedure:
/*
ERROR [HY000] ERROR: syntax error, unexpected VARIABLE, expecting BEGIN at or near "db_arg"
*/
The procedure looks like something like this:
CREATE OR REPLACE PROCEDURE LOAD_data_proc(CHARACTER VARYING(15))
RETURNS INTEGER
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
db_arg CHARACTER VARYING(15);
/* if I remove above declaration I get the following error message: ERROR [HY000] ERROR: ResolveCatalog: error retrieving database 'STG_DB_NAME' */
db_arg ALIAS FOR $1;
/* and bunch of other arguments and declarations */
BEGIN
/* logic here if then else statements */
END;
END_PROC;
Did anyone encounter this problem before?
It's not 100% clear from your description what the actual NZPLSQL code is, but I can reproduce your first error using:
CREATE OR REPLACE PROCEDURE LOAD_DATA_PROC(CHARACTER VARYING(15))
RETURNS INTEGER
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
db_arg CHARACTER VARYING(15);
db_arg alias for $1;
BEGIN
db_arg := 'SYSTEM';
RAISE NOTICE '%', db_arg;
RETURN 0;
END;
END_PROC;
Note there is a double declaration of the same variable name in the DECLARE block. This is not allowed, and this causes:
ERROR [HY000] ERROR: syntax error, unexpected VARIABLE, expecting BEGIN at or near "db_arg"
Removing one of the declarations will allow the procedure to complete.
IBM docs on NZPLSQL regarding parameter passing to stored procedures is available here: https://www.ibm.com/support/knowledgecenter/SSULQD_7.2.0/com.ibm.nz.sproc.doc/c_sproc_parameter_passing.html
and here:
https://www.ibm.com/support/knowledgecenter/SSULQD_7.2.0/com.ibm.nz.sproc.doc/c_sproc_arg_list.html
As for:
ERROR [HY000] ERROR: ResolveCatalog: error retrieving database 'STG_DB_NAME'
This occurs when I attempt to call a non-existent stored procedure, in a non-existent schema of a non-existent database such as:
CREATE OR REPLACE PROCEDURE LOAD_DATA_PROC(CHARACTER VARYING(15))
RETURNS INTEGER
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
db_arg alias for $1;
BEGIN
CALL UNKNOWNDB.UNKNOWN_SCHEMA.UNKNOWN_STORED_PROC(1234,5678,7890,123456,1234567);
END;
END_PROC;
which gives me:
ERROR [HY000] ERROR: ResolveCatalog: error retrieving database 'UNKNOWNDB'
Hopefully this helps to explain the errors and how to avoid them.
ok I figured it out... you can pass db_names as arguments to the netezza stored procedure but every time you use the argument inside the procedure, you have to use a dynamic query...
Hope this helps somebody, someday.

Wrapping a Stored Procedure

I have created a Stored Procedure in Oracle (Via TOAD).
I need to deliver this procedure to some other developers. All is need to do is Wrap the procedure so that at basic level he/she should not be able to view the code.
At the same time, the developer should be able to create the procedure and execute/test it.
my procedure is saved in say FileName.sql whose content are like:
Create or Replace Procedure
IS
Declaration
Begin
Code
End;
Now i want this FileName.sql to be wrapped. So that the encrypted file can be send to other to check in different environment.
Please help me in how to wrap, and then how the other guy will be able to create the procedure, and execute the same.
Thanks in advance.
The Oracle WRAP utility does exactly that - allows you to encode a stored procedure in a form suitable for shipping.
The wrapped code is as portable as source code, but cannot be examined as plain text.
You will need access to the command line using a suitable system user (i.e. one that has access to the Oracle binary commands e.g. sqlplus etc.) and the basic syntax is:
wrap iname=input_file [ oname=output_file ]
If you do not specify any extensions, the default for input is .sql and output is .plb
Once you have generated a .plb file, you can execute it against the database to create your stored procedure.
See:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/wrap.htm#LNPLS016
http://docs.oracle.com/cd/B10500_01/appdev.920/a96624/c_wrap.htm
WARNING
WRAPencoded procedures are not completely secure - it is possible to "unwrap" them.
A better way of using WRAP is to put the procedure(s) you wish to protect in a package and WRAP the package definition.
Let's say your procedure is:
CREATE OR REPLACE PROCEDURE PR_OUTPUT_TEXT(
P_TYPE IN CHAR,
P_TEXT IN VARCHAR2
) IS
V_TYPE CHAR(3) := UPPER(P_TYPE);
BEGIN
IF V_TYPE = 'LOG' THEN
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.LOG, TO_CHAR(SYSDATE,'HH24:MI:SS')||' - '||P_TEXT);
ELSE
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.OUTPUT, P_TEXT);
END IF;
END PR_OUTPUT_TEXT;
you would normally call it using:
EXECUTE PR_OUTPUT_TEXT('LOG', 'Kittehz!!!')
In a package you would define the package body and the procedure thus:
CREATE OR REPLACE PACKAGE BODY USER.MYPACKAGE AS
PROCEDURE PR_OUTPUT_TEXT(
P_TYPE IN CHAR,
P_TEXT IN VARCHAR2
) IS
BEGIN
IF V_TYPE = 'LOG' THEN
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.LOG, TO_CHAR(SYSDATE,'HH24:MI:SS')||' - '||P_TEXT);
ELSE
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.OUTPUT, P_TEXT);
END IF;
END PR_OUTPUT_TEXT;
END MYPACKAGE;
and you would call the package using:
EXECUTE USER.MYPACKAGE.PR_OUTPUT_TEXT('LOG', 'ERMAHGERD KERTERNS!!!')
From documentation, to be precise, this is what you need to do :
Running the wrap Utility
For example, assume that the wrap_test.sql file contains the following:
CREATE PROCEDURE wraptest IS
TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;
all_emps emp_tab;
BEGIN
SELECT * BULK COLLECT INTO all_emps FROM employees;
FOR i IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id);
END LOOP;
END;
/
To wrap the file, run the following from the operating system prompt:
wrap iname=wrap_test.sql
The output of the wrap utility is similar to the following:
PL/SQL Wrapper: Release 10.2.0.0.0 on Tue Apr 26 16:47:39 2005
Copyright (c) 1993, 2005, Oracle. All rights reserved.
Processing wrap_test.sql to wrap_test.plb
If you view the contents of the wrap_test.plb text file, the first line is CREATE PROCEDURE wraptest wrapped and the rest of the file contents is hidden.
You can run wrap_test.plb in SQL*Plus to execute the SQL statements in the file:
SQL> #wrap_test.plb
After the wrap_test.plb is run, you can execute the procedure that was created:
SQL> CALL wraptest();
More information in docs