Oracle ref cursor with slick - oracle

All.
We have an Oracle package that returns a ref cursor:
CREATE OR REPLACE PACKAGE BODY sandbox AS
FUNCTION my_function (text VARCHAR2) RETURN result_cv IS result result_cv;
BEGIN
OPEN result FOR SELECT MLS_SID FROM MLS;
RETURN result;
END;
END sandbox;
I am calling the function with the following scala code:
lazy val database = Database.forDataSource(DB.getDataSource())
database withSession {
val x = sql"select sandbox.my_function($text) from DUAL".as[(Int)]
x foreach (x => println(x))
Ok(String.valueOf(x.first))
}
The code fails with the following error:
[SQLException: Invalid column type: getInt not implemented for class oracle.jdbc.driver.T4CResultSetAccessor]
The SQL statement works when I just use the select statement that is in the function (SELECT MLS_SID FROM MLS;), but when I open it as a ref cursor and return the ref cursor it fails. I looked at the T4CResultSetAccessor and it only has one method getBytes().
Can anyone offer suggestions on how to make this work using the Oracle function call and ref cursors? Thanks in advance.
-patrick

Frome Typesafe:
Slick doesn’t support OUT parameters at the moment (which you would
need to properly return a ref cursor). If the cursor is all you need
to return from your stored proc, I suggest to use the method
recommended in the SO post: Lift the result set to the top level with
TABLE(). Does this work for your use case?
So our solution was to do this:
SELECT * FROM TABLE(my_function('text'))
We got an error, but that was Lucas' and Typesafe's suggestion

Related

Oracle: Create function that returns multiple rows

I have created a type inside a package and declared a function as below.
type backupStatus_t is table of d_backupstatus%ROWTYPE;
function getLatestBackupInfo return backupStatus_t;
Now, inside the package body, I have defined the function as below.
function getLatestBackupInfo RETURN backupStatus_t as
v_backupStatus backupStatus_t;
begin
select * bulk collect into v_backupStatus from d_backupstatus;
return v_backupStatus;
end;
Package compiles successfully.
When I try to call this function, I am getting "invalid datatype".
Can anyone help??
Try to create your "backupStatus_t" type outside of your package, like :
CREATE OR REPLACE TYPE backupStatus_t AS TABLE OF d_backupstatus%ROWTYPE;

How to execute Stored Procedure from Laravel - SQL Server

I have the following stored procedure:
ALTER procedure [dbo].[spx_kasir_verifikator_GetData_web]
#id_verifikator int
as
begin
SELECT * FROM tb_kasir_set_verifikator
WHERE tb_kasir_set_verifikator.id_verifikator = id_verifikator;
end
Controller:
public function show($id_verifikator)
{
$setverifikator = DB::select("exec spx_kasir_verifikator_GetData_web ?",[$id_verifikator]);
dd($setverifikator);
}
And I'm trying to call this procedure in Laravel 8, I need to display just one id or by id_verifikator but it's always showed all data. How I solve this?
It's returning everything as you are using select * which tells the database that you want the entire row. If you wish to only get a specific column then you need to change that to select id_verifikator.
A bit off-topic but I would suggest that you just run this query in Laravel instead of having a procedure, especially as this is such a basic query. The below links can help you get started.
https://laravel.com/docs/8.x/queries
https://laravel.com/docs/8.x/eloquent

FUNCTION in WHERE clause of SQL query

I have the following (private) PL/SQL function (inside PACKAGE) returning the previous month in 'YYYYMM' format:
FUNCTION GET_PREV_MONTH RETURN VARCHAR2 IS
BEGIN
RETURN TO_CHAR(ADD_MONTHS(SYSDATE,-1),'YYYYMM');
END GET_PREV_MONTH;
I need to compare if records are from previous month in several my queries so I wanted to make private function returning previous month. Why I cannot use this return value from GET_PREV_MONTH() function in WHERE clause of my other SQL queries like:
UPDATE mytable t SET t.col=1
WHERE TO_CHAR(t.created,'YYYYMM')=GET_PREV_MONTH();
Oracle says PLS_00231: function 'GET_PREV_MONTH' may not be used in SQL.
If I create this, this works!
UPDATE mytable t SET t.col=1
WHERE TO_CHAR(t.created,'YYYYMM')=TO_CHAR(ADD_MONTHS(SYSDATE,-1),'YYYYMM');
I wanted to make private function returning previous month. Why I cannot use this return value from GET_PREV_MONTH() function in WHERE clause of my other SQL queries
It is a private function - you cannot reference it outside the package.
If you want to use it in SQL then declare it in the package specification so that it is public.
This is private function of this package! This function is used in procedures from the same package. It is not referenced outside this package.
It CANNOT be used in the SQL context if it is not a public function; regardless of whether the SQL is being called from inside or outside the same package.

Oracle Stored Procedures with ADO NOT .net and VC++

I am migrating a VC++/SQL server app to using Oracle. The database access is implemented using ADO classes, and I can't find a way to go through the cursor that is returned by Oracle.
The sproc is something like:
create or replace PROCEDURE GetSettings
(
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT KEY ,
VALUE
FROM Settings;
END;
The code is something like:
_CommandPtr pCommand;
_ParameterPtr pParam1;
HRESULT hr = pCommand.CreateInstance (__uuidof (Command));
if (FAILED (hr))
return;
pCommand->ActiveConnection = m_pConn;
pCommand->CommandText = "GetSettings";
pCommand->CommandType = adCmdStoredProc;
_RecordsetPtr pRecordset;
hr = pRecordset.CreateInstance (__uuidof (Recordset));
if (FAILED (hr))
return;
pRecordset = pCommand->Execute(NULL,NULL,adCmdStoredProc);
(in fact it is using the ADO classes from http://www.codeproject.com/Articles/1075/A-set-of-ADO-classes-version-2-20#TheSample02 )
The returned pRecordset is in a closed state and you cannot do anything with it. I imagine I should pass some parameter for the cursor, but how do you create/use/access the returned cursor using these ADO functions? There is no cursor parameter type that I can see
I am completely stuck and would greatly appreciate some help
Thanks
Finally found out how to do it, you need specify special parameters in the connection string to tell it to return result set:
Provider=ORAOLEDB.ORACLE;User ID=xxx;Password=xxx;Data Source=tns_name;OLEDB.Net=True;PLSQLRSet=True;

How Can I get return values returned by stored procedure using InsertOnSubmit in LINQ

Can I get return values returned by stored procedure using InsertOnSubmit in LINQ.
The stored procedure return a error number. How can I get this error number InsertOnSubmit (using stored procedure instead of Runtime sql). Many Thanks
On the data-context are a number of partial methods for insert/update/delete of each entity type; if you implement the other half of this, you can provide your own SP logic:
partial class MyDataContext {
partial coid UpdateMyEntity(MyEntity instance) {
// your ADO.NET code and/or ExecuteCommand here...
}
}
Note that if you use a separate connection you won't have the same transaction etc (unless it uses TransactionScope).
I overloaded the default function generated by LINQ designer and followed the below steps.
Created a public readonly property _ReturnCode
In the overloaded function I used _ReturnCode = CType(result.ReturnValue, Integer)
Public Function FUNC_NAME( ByRef .....
Dim result As IExecuteResult = Me.ExecuteMethodCall(Me, CType(MethodInfo.GetCurrentMethod, MethodInfo), ......)
ID= CType(result.GetParameterValue(0), System.Nullable(Of System.Guid))
_ReturnCode = CType(result.ReturnValue, Integer)
Return CType(result.ReturnValue, Integer)
End Function
Let me know if anybody has a better answer. Many Thanks

Resources