How in ColdFusion with in variables get a Oracle stored procedure to return values? - oracle

ORACLE 11g - COLDFUSION 9 - REF CURSOR - WITH at least one in variable.
How in ColdFusion with in variables get a Oracle stored procedure to return values?
We have tried several things, we can get a stored procedure to return a result set if we are not passing in variables but we cannot get them when we are passing in variables.
We know how to do it calling MS SQL.
Thanks for any help
P.S. we have heard this may not be possible with the current Oracle Driver is there a different Oracle driver?
From what I have been reading online I am thinking this is not just a coding issue. I hope I am wrong about that. This is just an example I was working on as a proof of concept so I can start creating all of them. I can get it work if I am not using a ref cusor.
Error Executing Database Query.
[Macromedia][Oracle JDBC Driver]The specified SQL type is not supported by this driver.
The error occurred in D:\apache\htdocs\test\index.cfm: line 86
84 :
85 :
86 :
87 :
88 :
CF Call to procedure
<cfstoredproc procedure="BWNGDBADEV.PACK_REFCURSOR.GETALL" datasource="mydatasourcename" returncode="no">
<cfprocparam type="InOut" cfsqltype="CF_SQL_INTEGER" variable="pPERSONNELID" value="4" null="No">
<cfprocparam type="Out" cfsqltype="CF_SQL_REFCURSOR" variable="AnyVarName">
<!--- *** This name ties StoredProc results to the query below *** --->
<cfprocresult name="myvar">
</cfstoredproc>
Oracle Package
CREATE OR REPLACE
PACKAGE PACK_REFCURSOR
AS
TYPE EMP_TableRows
IS
REF
CURSOR
RETURN BWNGDBADEV.PER_PERSONNEL%ROWTYPE;
PROCEDURE GETALL(
pPERSONNELID IN OUT BWNGDBADEV.PER_PERSONNEL.PERSONNELID%type,
OUTTABLE OUT EMP_TableRows);
END PACK_REFCURSOR ;
/
CREATE OR REPLACE
PACKAGE BODY PACK_REFCURSOR
AS
PROCEDURE GETALL(
pPERSONNELID IN OUT BWNGDBADEV.PER_PERSONNEL.PERSONNELID%type,
OUTTABLE OUT EMP_TableRows)
IS
BEGIN
-- implicit cursor is opened - no close needed ***
OPEN OUTTABLE FOR
SELECT *
FROM BWNGDBADEV.PER_PERSONNEL
WHERE PERSONNELID = pPERSONNELID;
END GETALL ;
END PACK_REFCURSOR ;
/

do you have the latest DataDirect JDBC drivers ?
v 3.5 drivers and release notes here: http://kb2.adobe.com/cps/000/42dcb10a.html
the release notes suggest it fixes your exact problem

There's a small note in the docs stating: "You cannot use the cfprocparam tag for Oracle 8 and 9 reference cursors. Instead, use the cfprocresult tag."
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d52.html
Try something along these lines:
<cfstoredproc
procedure = "BWNGDBADEV.PACK_REFCURSOR.GETALL"
dataSource = "mydatasourcename"
returnCode = "Yes">
<!--- cfprocparam tags --->
<cfprocparam type="InOut" cfsqltype="CF_SQL_INTEGER" variable="pPERSONNELID" value="4" null="No">
<cfprocparam type="Out" cfsqltype="CF_SQL_REFCURSOR" variable="AnyVarName">
<!--- cfprocresult tags --->
<cfprocresult name="RS1" resultSet="1">
<cfprocresult name="RS2" resultSet="2">
</cfstoredproc>

Related

IIB v10: Passing local variable to ESQL select statement

I am new to IIB, trying to connect to Oracle DB using ESQL. Trying to pass a local param to where clause in simple SELECT statement. Getting below error while executing it. Can anyone help me out
ESQL:
BROKER SCHEMA com.project
CREATE COMPUTE MODULE MainFlow_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
DECLARE var REFERENCE TO Environment.Variables;
DECLARE username CHAR;
SET username = InputRoot.JSON.Data.userid;
--SET OutputRoot.XML.Invoice[] = SELECT E.EMPLOYEE_ID,E.FIRST_NAME FROM Database.HR.EMPLOYEES AS E WHERE E.EMPLOYEE_ID=username;
SET OutputRoot.XML.Invoice[] = PASSTHRU('SELECT E.EMPLOYEE_ID,E.FIRST_NAME FROM Database.HR.EMPLOYEES AS E WHERE E.EMPLOYEE_ID=?' VALUES(username));
SET OutputRoot.JSON.Data.user_id=username;
--SET OutputRoot.JSON.Data.user_name=var.profile.FIRST_NAME;
RETURN TRUE;
END;
END MODULE;
Log:
Error: BIP3113E: Exception detected in message flow com.project.MainFlow
http://localhost:7800/users/getUserDetails
Exception. BIP2230E: Error detected whilst processing a message in node 'com.project.MainFlow.Compute'. : F:\build\slot2\S1000_P\src\DataFlowEngine\SQLNodeLibrary\ImbComputeNode.cpp: 515: ImbComputeNode::evaluate: ComIbmComputeNode: com/project/MainFlow#FCMComposite_1_4
BIP2488E: ('com.project.MainFlow_Compute.Main', '14.4') Error detected while executing the SQL statement ''SET OutputRoot.XML.Invoice[] = DEFAULTPASSTHRU('SELECT E.EMPLOYEE_ID,E.FIRST_NAME FROM Database.HR.EMPLOYEES AS E WHERE E.EMPLOYEE_ID=?', username);''. : F:\build\slot2\S1000_P\src\DataFlowEngine\ImbRdl\ImbRdlStatementGroup.cpp: 767: SqlStatementGroup::execute: :
BIP2321E: Database error: ODBC return code '-1' using ODBC driver manager ''odbc32.dll''. : F:\build\slot2\S1000_P\src\DataFlowEngine\MessageServices\ImbOdbc.cpp: 3814: ImbOdbcStatement::checkRcInner: :
BIP2322E: Database error: SQL State ''IM001''; Native Error Code '0'; Error Text ''[Microsoft][ODBC Driver Manager] Driver does not support this function''. : F:\build\slot2\S1000_P\src\DataFlowEngine\MessageServices\ImbOdbc.cpp: 4035: ImbOdbcStatement::checkRcInner: :
Note: I have referred to below link already
IIB: Passing local variable to ESQL select statement

how to insert a giant geometry into a field of type SDO_GEOMETRY?

I am trying to insert this http://pastebin.com/cKXnCqx7 geometry into an SDO_GEOMETRY field, as follows:
declare
str clob = http://pastebin.com/cKXnCqx7
begin
INSERT INTO TEMP_TEST_GEOMETRY VALUES (SDO_CS.TRANSFORM (SDO_GEOMETRY (str, 4674), 1000205));
end;
And is generating the following error:
The maximum size of a string literal is 32K in PL/SQL. You're trying to assign a 98K+ literal, which is what is causing the error (although since that refers to 4k, that seems to be from a plain SQL call rather than the PL/SQL block you showed). It isn't getting as far as trying to create the sdo_geometry object from the CLOB.
Ideally you'd load the value from a file or some other mechanism that presents you with the complete CLOB. If you have to treat it as a literal you'd have to manually split it up into chunks; at least 4 with this value if you make them large:
declare
str clob;
begin
dbms_lob.createtemporary(str, false);
dbms_lob.append(str, 'POLYGON ((-47.674240062208945 -2.8066454423517624, -47.674313162 -2.8066509996, <...snip...>');
dbms_lob.append(str, '47.6753521374 -2.8067875453, -47.6752566506 -2.8067787567, -47.6752552377 -2.8067785117, <...snip...>');
dbms_lob.append(str, '-47.658134547 -2.8044846153, -47.6581360233 -2.8044849964, -47.6581811229 -2.8044926289, <...snip...>');
dbms_lob.append(str, '-47.6717079633 -2.8057792966, -47.6717079859 -2.80577931, -47.6717083252 -2.8057795101, -47.6718125136 -2.8058408619, -47.6719547186 -2.8059291721, -47.6719573483 -2.8059307844, -47.6719575243 -2.8059308908, -47.6719601722 -2.8059324729, -47.6720975574 -2.8060134925, -47.6721015308 -2.8060157903, -47.6721017969 -2.8060159412, -47.6721058088 -2.806018171, -47.6721847946 -2.8060611947, -47.6721897923 -2.8060650985, -47.6722059263 -2.8060767675, -47.6722070291 -2.8060775047, -47.6722416572 -2.8060971165, -47.6722428566 -2.8060976832, -47.6722611616 -2.8061055189, -47.6722666301 -2.8061076243, -47.6722849174 -2.806116847, -47.6722862515 -2.8061174528, -47.6723066339 -2.8061257231, -47.6723316499 -2.8061347029, -47.6723426416 -2.8061383836, -47.6723433793 -2.8061386131, -47.672354519 -2.8061418177, -47.6723803034 -2.8061486384, -47.6725084039 -2.8061908942, -47.6725130545 -2.8061923817, -47.6725133654 -2.806192478, -47.6725180423 -2.806193881, -47.6728423039 -2.8062879629, -47.6728698649 -2.8062995965, -47.6728952856 -2.8063088527, -47.672897007 -2.8063093833, -47.672949984 -2.8063200428, -47.6729517767 -2.8063202193, -47.672966443 -2.8063209226, -47.6729679855 -2.8063213223, -47.6733393514 -2.8064196858, -47.6733738728 -2.8064264543, -47.6733761939 -2.8064267537, -47.6733804796 -2.8064270239, -47.6733890639 -2.806431641, -47.6734057692 -2.8064398944, -47.6734069006 -2.8064404055, -47.6734241363 -2.8064474849, -47.6736663052 -2.8065373005, -47.6736676833 -2.8065378073, -47.6736677752 -2.8065378409, -47.673669156 -2.8065383402, -47.6737754465 -2.8065764489, -47.673793217 -2.8065850801, -47.6737945765 -2.8065856723, -47.6738366895 -2.8066000123, -47.6738381279 -2.8066003728, -47.6738811819 -2.8066074503, -47.6739137725 -2.8066153813, -47.6739159177 -2.806615636, -47.6739318345 -2.8066165588, -47.673951326 -2.806622013, -47.6739530661 -2.8066223195, -47.6739793945 -2.8066256302, -47.6740948445 -2.8066344025, -47.674240062208945 -2.8066454423517624))');
INSERT INTO TEMP_TEST_GEOMETRY
VALUES (SDO_CS.TRANSFORM (SDO_GEOMETRY (str, 4674), 1000205));
dbms_lob.freetemporary(str);
end;
/
You can make the chunks smaller and have many more appends, which may be more manageable in some respects, but is more work to set up. It's still painful to do manually though, so this is probably a last resort if you can't get the value some other way.
If the string is coming from an an HTTP call you can read the response in chunks and convert it into a CLOB as you read it in much the same way, using dbms_lob.append. Exactly how depends on the mechanism you're using to currently get the response. Also worth noting that Oracle 12c has built-in JSON handling; in earlier versions you may be able to use the third-party PL/JSON module, which seems to handle CLOBs.

Mule: Invoking an Oracle stored procedure which returns a table of custom type

I am using Mule CE 3.6.1. I have the following Database connector configuration calling an Oracle stored procedure.
<db:stored-procedure config-ref="Oracle_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[call get_phone_email(:userId, :tPhoneRecord)]]></db:parameterized-query>
<db:in-param name="userId" type="NUMERIC" value="#[payload]" />
<db:out-param name="tPhoneRecord" type="ARRAY" />
</db:stored-procedure>
Parameter tPhoneRecord is defined as IS TABLE OF phone_email%ROWTYPE (i.e. table of records) in the stored procedure. I have tried specifying the parameter type ARRAY but get the error:
Message : Invalid argument(s) in call (java.sql.SQLException). Message payload is of type Object[]
Code : MULE_ERROR--2
I have also tried using other out-param types or not specifying a type without success.
Please let me know what out-param type I should use for an Oracle table of records, or if I should do this in Java instead. Many thanks in advance.
You can use the below solution for out parameter.
<db:oracle-config name="Oracle_Configuration" url="jdbc:oracle:thin:#54.175.245.218:1581:xe" user="user" password="4321" >
</db:oracle-config>
<db:data-type name="INtypename" id="12"/>
<!-- VARCHAR id=12 -->
<db:data-type name="OUTtypename" id="2002"/>
<!-- STRUCT id=2002 -->
</db:data-types>
...
<db:stored-procedure config-ref="Generic_Database_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[CALL storedprocfnc(:INtypename,:OUTtypename);]]></db:parameterized-query>
<db:in-param name="INtypename" value="#[payload]"/>
<db:out-param name="OUTtypename" />
</db:stored-procedure>

Test the existence of a Teradata table and create the table if non-existent

Our Continuous Inegration server (Hudosn) is having a strange issue when attempting to run a simple create table statement in Teradata.
This statement tests the existence of the max_call table:
unless $teradata_connection.table_exists? :arm_custom_db__max_call_attempt_parameters
$teradata_connection.run('CREATE TABLE all_wkscratchpad_db.max_call_attempt_parameters AS (SELECT * FROM arm_custom_db.max_call_attempt_parameters ) WITH NO DATA')
end
The table_exists? method does the following:
def table_exists?(name)
v ||= false # only retry once
sch, table_name = schema_and_table(name)
name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
from(name).first
true
rescue DatabaseError => e
if e.to_s =~ /Operation not allowed for reason code "7" on table/ && v == false
# table probably needs reorg
reorg(name)
v = true
retry
end
false
end
So as per the from(name).first line, the test which this method is performing is just a simple select statement, which, in SQL, looks like: SELECT TOP 1 MAX(CAST(MAX_CALL_ATTEMPT_CNT AS BIGINT)) FROM ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS
The above SQL statement executes perfectly fine within Teradata SQL Assistant, so it's not a SQL syntax issue. The generic ID which our testing suite (Rubymine) uses is also not the issue; that ID has select access to the arm_custom_db.
The exeption which I can see is being thrown (within the builds console output on Hudson) is
Sequel::DatabaseError: Java::ComTeradataJdbcJdbc_4Util::JDBCException. Since this execption is a subclass of DatabaseError, the exception shouldn't be the problem either.
Also: We use unless statements like this every day for hundreds of different tables, and all except this one work correctly. This statement just seems to be a problem.
The complete error message which appears in the builds console output of Hudson is as follows:
[2015-01-07T13:56:37.947000 #16702] ERROR -- : Java::ComTeradataJdbcJdbc_4Util::JDBCException: [Teradata Database] [TeraJDBC 13.10.00.17] [Error 3807] [SQLState 42S02] Object 'ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS' does not exist.: SELECT TOP 1 MAX(CAST(MAX_CALL_ATTEMPT_CNT AS BIGINT)) FROM ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS
Sequel::DatabaseError: Java::ComTeradataJdbcJdbc_4Util::JDBCException: [Teradata Database] [TeraJDBC 13.10.00.17] [Error 3807] [SQLState 42S02] Object 'ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS' does not exist.
I don't understand why this specific bit of code is giving me issues...there does not appear to be anything special about this table or database, and all SQL code executes perfectly fine in Teradata when I am signed in with the same exact user ID that is being used to execute the code from Hudson.

BCB: from BDE to dbexpress, BCD exception

I'm having some problem about TSQLStoredProcedure. Here is the code:
storedproc->ParamByName("A")->AsInteger = adataset->FieldByName("AA")->AsInteger;
storedproc->ExecProc();
param "A" is declared integer in the form (and it's 29 in the program). Also the stored procedure has no errors. I'm sure of it. Database is Oracle 11g. By the way, as storedproc is executed an exception occurred:
...
EBcdException with message '<0000001:000000010000000:00000063612>' is not a valid BCD value
...
All was working fine with BDE but now, using dbexpress, there is this problem. I searched over the internet for some days and I did not find an answer.
I thank you in advance and beg a pardon for my English.
Francesco
Update
I searched over the web. I found something interesting at:
https://forums.codegear.com/thread.jspa?messageID=43223&tstart=0
http://www.delphigroups.info/2/8/750511.html
I decide to make some test:
SQLQuery->ParamByName("f1")->AsString = Edit1->Text;
SQLQuery->ExecSQL();
It works. Not the same for
SQLQuery->ParamByName("f1")->AsInteger = StrToInt(Edit1->Text); //ERROR DBX Error: Invalid Field Type.
SQLQuery->ParamByName("f1")->AsFloat = StrToFloat(Edit1->Text); //ERROR DBX Error: Invalid Field Type.
SQLQuery->ParamByName("f1")->AsBCD = StrToInt(Edit1->Text); //ERROR ORA-06502: PL/SQL: error: ... ORA-06512: at line 1.
SQLQuery->ParamByName("f1")->AsFMTBCD = StrToBcd(Edit2->Text); //ERROR ORA-06502: PL/SQL: error: ... ORA-06512: at line 1.
or by using TSQLStoredProc.
So now I call my pl/sql stored proc by TSQLQuery. I use "AsString" to pass values to parameters. Weird. How does dbexpress map types? Thanks in advance.

Resources