We are porting Oracle Pro*C code to PostgreSQL ECPG. We had several Oracle stored procedures that were ported into PostgreSQL functions like:
db1.update_some_logic(double precision, double precision, text, text)
On the C file I've tried several things but nothing seems to work.
Option 1:
EXEC SQL SELECT db1.update_some_logic(10411, 920, 'TYT','N');
Error 1:
too few arguments on line 4379
Option 2:
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt2 = "SELECT db1.update_some_logic(10411, 920, 'TYT','N');";
EXEC SQL END DECLARE SECTION;
EXEC SQL EXECUTE IMMEDIATE :stmt2;
Error 2:
too few arguments on line 4384
The function clearly has 4 arguments, not sure what I am missing here.
I can reproduce the issue with PostgreSQL 12.3.
I have found following workaround:
the function should not return void but a value for example an integer
the ECPG program must execute the function and get the returned value with SELECT ... INTO:
EXEC SQL SELECT update_some_logic(10411, 920, 'TYT','N') INTO :v_key;
You'll need work with share variables for those parameters.
EXEC SQL BEGIN DECLARE SECTION;
double parameter_1;
double parameter_2;
char parameter_3[100];
char parameter_4[100];
int result; //I guess your function return int??
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT update_some_logic(:parameter_1, :parameter_2, :parameter_3, :parameter_4) INTO :result;
if (sqlca.sqlcode!=0)
{
printf("Error: %ld\n", sqlca.sqlcode);
printf("Message:%s\n", sqlca.sqlerrm.sqlerrmc);
}
printf("It works %d\n", result);
Related
I am working in a migration project, where lift and shift method is used to migrate SQL server DB from onprem to AZure Cloud. There is a lot of stored procedures used for integration in On prem.Now here in On prem , to process the XMl file and execute the same procedures pointing to the cloud Db I need to write a code in Databricks. I have code to execute a single stored procedure using Scala, as I am new to coding in python/scala I couldn't find the right method to execute the procedures.
The below code is what I have used to execute one procedure- sample
%scala
val username = "xxxxx"
val pass = "xxxxx"
val url = "jdbc:sqlserver://xxx.database.windows.net:1433;databaseName=xxx"
val table = "SalesLT.Temp3"
val query = s"EXEC sp_truncate_table '${table}'"
val conn = DriverManager.getConnection(url, username, pass)
val rs = conn.createStatement.execute(query)
I have a requirement to execute some 10 stored procedures in series.
Looking forward for your suggestions.
To run multiple stored procedures sequentially you can create one Stored procedure and call all your stored procedures in that and call this stored procedure through Databricks.
The following code example is referred from here by #Thom A
CREATE PROC MySP1 #int int AS
PRINT #int / 0; --To error
GO
CREATE PROC MySP2 #int int AS
PRINT #int + 1;
GO
CREATE PROC MySP3 #int int AS
PRINT #int + 2;
GO
CREATE PROC AllMySPs #Int int AS
PRINT 'Executing SP1...';
BEGIN TRY
EXEC MySP1 #Int;
END TRY
BEGIN CATCH
PRINT 'MySP1 failed';
END CATCH
PRINT 'Executing SP2...';
BEGIN TRY
EXEC MySP2 #Int;
END TRY
BEGIN CATCH
PRINT 'MySP2 failed';
END CATCH
PRINT 'Executing SP3...';
BEGIN TRY
EXEC MySP3 #Int;
END TRY
BEGIN CATCH
PRINT 'MySP3 failed';
END CATCH
GO
CREATE OR ALTER FUNCTION sso.FINDSEQVALUE
(#sequence_text text)
RETURNS int
AS
BEGIN
DECLARE #value int;
DECLARE #sequence_value nvarchar(150);
SELECT #sequence_value = CAST(#sequence_text AS nvarchar(150));
SELECT #value = NEXT VALUE FOR #sequence_value;
RETURN #value;
END;
I have a problem. I have created a function on SQL Server and I defined the parameter as you can see. But I cannot add the this command #sequence_value after NEXT VALUE FOR command and I am getting an error.
Incorrect syntax near '#sequence_value'
Somebody can say that "You can use (SELECT NEXT VALUE FOR [SEQUENCE])". But I need this function because of there are two different database on my project. I need same function for databases. In addition function parameter need to be text.
What should I do?
I am trying to build a C program to generate partly random strings and insert a large number of them to db2 rows in a loop so I need it to insert from embedded SQL.... The program does everything except inserts.
I can make a select query, c compiler, db2 precompiler and binder all execute with no errors.
It does not even let me make an insert with hard coded variables let alone with host variables and the query is perfectly successful from terminal line
db2 "INSERT INTO
SYT006_COUNTRY(SL_ISO2,BZ_COUNTRY,KZ_RISK)
VALUES
('XY', 'wont work from embedded SQL', 'R')"
Host variables defined as char arrays with one more position for terminator. Platform is Ubuntu.
I tried a million things so here is the code.. EDIT everything obsolete cleared
#include <stdio.h>
#include <string.h>
#include <sqlca.h>
#include <stdlib.h>
#include <sqlenv.h>
#include <sqlcodes.h>
#include <sqlutil.h>
#include <time.h>
#include "utilemb.h"
#include "sqlaprep.h"
/* SQL includes */
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL DECLARE SYT006_COUNTRY TABLE
(
KEYFIELD INT,
SL_ISO2 CHAR(2) NOT NULL,
BZ_COUNTRY CHAR(30) NOT NULL,
KZ_RISK CHAR(1) NOT NULL
) ;
char hostVar[31];
EXEC SQL END DECLARE SECTION;
int main()
{
/* connect to the database REQUIRED */
printf("Connecting to database...\n ");
EXEC SQL CONNECT TO "sample";
if (SQLCODE <0)
{
printf("Connect Error. Code: %d\n", sqlca.sqlcode);
}
else
{
printf("Connected to database. Code: %d\n",sqlca.sqlcode );
}
/* works only from command line terminal*/
EXEC SQL
INSERT INTO
SYT006_COUNTRY(SL_ISO2,BZ_COUNTRY,KZ_RISK)
VALUES
('XY', 'please', 'R');
/* this one works perfectly normal*/
/*
EXEC SQL SELECT BZ_COUNTRY INTO :hostVar
FROM SYT006_COUNTRY WHERE KEYFIELD = 515;
printf("printing hostVar: %s\n", hostVar);
*/
printf("MAIN FINISH \n");
return (0);
}/*end main*/
the only out of order thing I get is when i start db2 from my shell script:
SQL5043N Support for one or more communications protocols specified in the DB2COMM environment variable failed to start successfully. However, core database manager functionality started successfully.
SQL1063N DB2START processing was successful.
Nothing better then a cup of coffee the next day.
Embedded-SQL program requires the line
EXEC SQL COMMIT;
I'm trying to prepare stored procedure with TDS_DYN_PREPARE like
'create proc dyn1 as EXEC #RETURN_VALUE = sel_from_emp'
If I trying to use statement as is error 'Must declare variable '#RETURN_VALUE'
If parameter name replaced with ? (required for input params, but I tried on return value too) error
'The untyped variable ? is allowed only in in a WHERE clause or the SET clause of an UPDATE statement or the VALUES list of an INSERT statement'
Is it possible to use return value in such statement and if yes - how?
What you're doing here is executing a proc named sel_from_emp which apparently returns a status value (ASE procs can do that). Is this what ypu expected?
This status value is captured in variable #RETURN_VALUE -- but that variable is not declared, so you must add a statement DECLARE #RETURN_VALUE INT.
Note that capturing the proc return statis mskes sense pmly when you sre going to do domething with that value, otherwise you can you do EXEC sel_from_emp.
I have the below code in my .pc file which is called by almost 10 processes but for one process its not working as showing "Core dump/Segmentation Fault" .
This is the code which is called by every process as the first step to connect to Database.
Please suggest where is the problem in the below code -:
void DatabaseLogon (void)
{
EXEC SQL BEGIN DECLARE SECTION;
char *pchORALOG="";
EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER SQLERROR DO SQLError();
/* Save text of current SQL statement in the ORACA if an error occurs. */
oraca.orastxtf = ORASTFERR;
/* try to get the oracle login user/pass at the process level */
if ( (pchORALOG=getenv("oralog")) == NULL )
{
printf("Error:Cannot Logon to database!\n");
SQLError();
}
else
{
EXEC SQL CONNECT :pchORALOG;
}
} /* End Of DatabaseLogon */
Thanks
Arpita
My ProC connect statement looks like this:
EXEC SQL CONNECT :user IDENTIFIED BY :passwd USING :database;
you are trying to modify a read only location here.
pchORALOG=getenv("oralog")
below statement is the problem:
char *pchORALOG="";
change it to:
char *pchORALOG;