Calling PL/SQL functions in SQL

Hi,
I had a question on the behaviour of PL/SQL function when they are embedded in SQL queries.
I have simple PL/SQl function:
function get_city_id
(vCUSTOMER_GROUP_ID IN NUMBER)
RETURN VARCHAR2 AS
vIDs VARCHAR2(1000);
begin
vIDs := '2,3';
RETURN vIDs;
end;
I use an SQL query call this PL SQL function;
select equipment_id from equipment where equipment_type_id in (get_city_id(0));
When I run this query I get this error:
ERROR at line 1:
ORA-01722: invalid number
I understand that the SQL compiler is complaining that get_city_id() function is not returning a number. but isn't the PL/SQL suppose to be replace with whatever string is returned from the function.
This brings me to the second question: How can we return multiple values from a function to the SQL query, when the function is called in a SQL query. In my above explame, can the get_city_id() function return more than one city id and if yes, the how?
Thanks for the help in advance
regards
Alankar

How can we return multiple values from a function to the SQL query,Have it return a collection, e.g.
CREATE OR REPLACE TYPE VARCHAR2_TT AS TABLE OF VARCHAR2(4000)
CREATE OR REPLACE FUNCTION test_collection
    RETURN VARCHAR2_TT
AS
BEGIN
    RETURN VARCHAR2_TT(1,2,3);
END;
SELECT *
FROM   employees
WHERE  emp_id IN
       ( SELECT column_value
         FROM   TABLE(test_collection) );

Similar Messages

  • How to return less than 4000 characters from pl/sql function in SQL call?

    Hello,
    Is there a way to limit length for varchar when calling pl/sql function from SQL? No matter how I write it it always returns 4000 bytes.
    If there is none, then does it make sense ever to specify lenght of the return variable?
    My goal is to encapsulate business rules within pl/sql functions. But if all varchar columns are returned as 4000 it is not feasible solution. Not only this is a performance issue in a data warehousing environment, bet when using those rules within SQL views user experiance would suffer as well. Are we left with the rule hardcoding solution? Also, I think that using SUBSTRING or TRUNC functions on top of business rules function defeats the purpose.
    Please see my attempt below. Your thoughts are appreciated.
    Thank you.
    /* Formatted on 06/11/2009 2:26:41 PM (QP5 v5.126.903.23003) */
    CREATE OR REPLACE FUNCTION mytest (myvar_in VARCHAR2)
    RETURN VARCHAR2
    AS
    l_return VARCHAR2 (15);
    BEGIN
    l_return := 'TEST_' || myvar_in;
    RETURN l_return;
    END mytest;
    CREATE TABLE TEST_ME
    AS
    SELECT mytest ('ME') AS VERYLONG FROM DUAL;
    describe TEST_ME;
    RUN ABOVE CODE:
    Function created.
    Table created.
    TABLE TEST_ME
    Name Null? Type
    VERYLONG VARCHAR2(4000)
    Edited by: Ilmars2 on Jun 11, 2009 2:46 PM

    Pointless,
    Thanks for jumping in on this and I am glad you asked :).
    I do not doubt that it is an architectural challenge. Otherwise it would have been done already! I am struggling with the fact that SQL knows what data type the function will return, but does not know the length of it, precision or scale. I will leave it at that.
    I will go with some high level requirements to allow for alternative thoughts:
    1)     Business defined rules. There are multiple types of business rules. Simple lookups, bucketing, complex calculations, data retrieved from other tables etc. We have about 500 different rules. Some of them are even overloaded – different inputs will produce the same output.
    Some simple examples are:
    Rule1 - Fruit
         when ‘A’ then ‘Apple’
         When ‘O’ then ‘Orange’
         Else ‘N/A’ end
    Rule2 – Bonus
         when STATUS =’Active’ and LEVEL=’CEO’ then bonus=salary*1.0
         when STATUS =’Active’ and LEVEL=’nobody’ then bonus=salary*0.01
         else bonus=0
    Rule 3 – Income Bracket
         When more than 0 and less or equal to 30000 then INC_B=’LOW’
         When more than 30000 and less of equal to 60000 then INC_B=’MIDDLE’
    Etc.
    2)     Challenge: All data users in an organization need to use the same rules (let’s assume data source is Oracle database). How to expose all the rules to different types of users in manageable way? Types of users – analysts, application/web developers, data warehouse teams etc.
    3)     Current system: Not only each user has coded their own rules (luckily based on the common specification), but hard-coding is taking place for each query within the confines of one project. The project I just looked at had about 12 modules with 30 hardcoded queries. Oops! Few rules just changed.
    My take: I was leaning toward encapsulating business logic within UDF’s. UDF’s provide all the flexibility we need + overloading. All the functions could be consumed by data warehouse team (building summary tables, cubes etc.) and application developers. For power users we could build views by applying the same functions on top of the source data. Thus avoid data duplication. It seemed win-win until this 4000 issue :).
    Your thoughts on alternative approaches are appreciated.
    Thank you.

  • Report- Pl/sql function returning sql query parsing page items as text?

    Hi Team,
    I am facing a strange issue .
    I have four page items namely
    1)JOB_CODE
    2)MIN_EXP
    3) MAX_EXP
    4) SOURCES1
    I have a report of the type "Pl/sql function returning sql query"
    declare
    v_sql varchar2(4000);
    begin
    if (:JOB_CODE IS NOT NULL and :MIN_EXP IS NOT NULL and :MAX_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql:= 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = :JOB_CODE and v_experience_years >= :MIN_EXP and v_experience_years <= :MAX_EXP and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    elsif (:JOB_CODE IS NULL and :MIN_EXP IS NOT NULL and :MAX_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql := 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where v_experience_years >= :MIN_EXP and v_experience_years <= :MAX_EXP and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    elsif (:MIN_EXP IS NULL and :JOB_CODE IS NOT NULL and :MAX_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql := 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where v_experience_years <= :MAX_EXP and V_REQUIREMENT = :JOB_CODE and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    elsif (:MAX_EXP is null and :JOB_CODE IS NOT NULL and :MIN_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql := 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = :JOB_CODE and v_experience_years >= :MIN_EXP and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    end if;
    insert into query_list values (v_sql);
    insert into debug values (:JOB_CODE , :MIN_EXP , :MAX_EXP , :SOURCES1);
    return v_sql;
    end;
    Please not that I am insertin the query into a table called Query_list and the page item values into the table called Debug thru the pl/sql function which returns teh query.
    Now I select the data from the debug tables.
    select unique(query) from query_list;
    select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = :JOB_CODE and v_experience_years >= :MIN_EXP and v_experience_years <= :MAX_EXP and source like '%:SOURCES1%'
    select * from debug;
    JOBCODE     MINEX     MAXEX     SOURCE
    21     1     10     donkeyHire
    And if I run the query in sql I get some records returned
    select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = 21 and v_experience_years >= 1 and v_experience_years <= and source like 'donkeyHire'
    V_CANDIDATE_ID     V_FNAME     V_CURRENT_EMPLOYER     V_EXPERIENCE_YEARS
    2     Vengu     Andale Tech     4
    But the record does not show up in the report!
    does this type of report parse page items as text?
    Why is it so?
    Waiting for an early reply.
    Thanks,
    venkat

    Venkat - You don't want to put ':SOURCES1' in quotes like that.
    Scott

  • Issue with running PL/SQL function returning Sql query

    hi, I am trying to create a report region by using the option of PL/SQL function returning sql query.
    I notice that it's very slow for the report region page to show up. In my PL/SQL function body, there are only 3 steps, first update all the 10 rows of varchar2 fields to null,then insert values to those fields, then select all from the table to show report results. It takes more than 5 minitues for the page to load up, how ever, if i run those steps in SQL*Plus, it only takes a couple of seconds to finish. Any suggestions?
    Thanks,
    gina

    Sergio, the codes are as followed,
    Declare
    q varchar2(32767); -- query
    Begin
    q := 'select "ID",'||
    '"ENTRY NAME","TOTAL","#CM","%CM","#CA",'||
    '"%CA", from Info_table';
    update info_table
    set "TOTAL" = '',
    "#CM" = '',
    "%CM" = '',
    "#CA" ='',
    "%CA"=''
    where "ID"<=10;
    // set all data in column Total to null,there is only 10 rows in the table
    update info_Table set Total = vTotal,
    "#CM" = vCM
    (those variables hold user key-in Text filed value)
    where ID = 1;
    return q;
    End;

  • On Submit process not firing -report (PL/SQL function returning SQL query)

    Can anyone suggest possible causes / solutions for the following problem?
    I have a report region that uses a PL/SQL function returning SQL query. The report allows the user to update multiple fields / rows and then click a button to submit the page which should run the On-Submit process to update the database. However the process does not run and I get a 'HTTP404 page cannot be found' error; and when I navigate back using the Back button I cannot then navigate to any other page in my application without getting the same error. The button was created by a wizard selecting the options to submit the page and redirect to a (same) page. The button does not actually have a redirect in its definition but the wizard created a branch to the same page which should work and the button has the text 'submit as SUBMIT' next to it so it appears to be set up correctly.
    I have recreated this page several times in my application and I cannot get the On-Submit process to run. However I have created a cut down version of the same page in the sample application on apex.oracle.com at http://apex.oracle.com/pls/otn/f?p=4550:1:179951678764332 and this works perfectly so I am at a loss to understand why it does not work in my application. I cannot post any part of the application itself but if anybody would like to check out page 30 of the sample application (Customer Update Test tab) updating the surnames only, using credentials ja, demo, demo this is pretty much what I have got in my application.
    Any ideas would be much appreciated?

    Thanks for the suggestions guys. I have now identified that the problem goes away when I remove the second table from my report query. The original report query retrieved data from two tables and the process was updating only one of the tables. I thought I had approached the task logically i.e. first get the report to display the records from the two tables, then get the process to update the first table and finally to modify the process further to update the second table.
    Can anyone point me to an example of multiple row updates on multiple tables using a PL/SQL function returning an SQL query?

  • SQL Query(PL/SQL Function Returning SQL Query)

    I am trying to write a dynamic report using SQL Query(PL/SQL Function Returning SQL Query).
    I can get the report to run but I need to concatinate some columns into one, seperated by a comma or a dash.
    I have tried select *****||','||***** alias
    also select *****||'-'||***** alias
    but I always get an error.
    Is there a way of doing this please
    Gus

    This is my full query
    declare
    v_query varchar2(4000);
    begin
    if :P63_TRAN_INFO = 2 THEN
    v_query := 'select
         A.FILENR,
         A.EXERCISENAME,
    A.STARTDATE,
    A.ENDDATE,
         A.UNIT,
    A.ACCADDRESSES, B.ADDRESS, B.ADDRESS_1, B.POST_CODE, B.TOWN,
         A.EXERCISEAREAS,
         A.TOTALVEHICLES,
    A.TOTALTROOPS+A.RNTOTALTROOPS+A.RAFTOTALTROOPS TOTALTROOPS,
    A.CAR, A.MINIBUS, A.HGV,
    A.NAMERANK, A.ADDRESS, A.ADDRESSI, A.ADDRESSII, A.POSTCODE,
    A.TRANSIT,
    A.INFOONLY
    from     BFLOG_AT A, BFLOG_ACCADDRESS B
    WHERE A.ACCADDRESSES = B.NAME
    AND A.STARTDATE >= :P63_START_DATE
    AND A.ENDDATE <= :P63_END_DATE
    AND A.AUTHORISED = 1
    AND A.INFOONLY = 1' ;
    END IF;
    RETURN v_query;
    END;
    This query runs ok, but if I try changing it to the code below with fields concatinated, then it fails
    declare
    v_query varchar2(4000);
    begin
    if :P63_TRAN_INFO = 2 THEN
    v_query := 'select
         A.FILENR,
         A.EXERCISENAME,
    A.STARTDATE,
    A.ENDDATE,
         A.UNIT,
    A.ACCADDRESSES||','||B.ADDRESS||','||B.ADDRESS_1||','||B.POST_CODE||','||B.TOWN ADDRESS,
         A.EXERCISEAREAS,
         A.TOTALVEHICLES,
    A.TOTALTROOPS+A.RNTOTALTROOPS+A.RAFTOTALTROOPS TOTALTROOPS,
    A.CAR, A.MINIBUS, A.HGV,
    A.NAMERANK, A.ADDRESS, A.ADDRESSI, A.ADDRESSII, A.POSTCODE,
    A.TRANSIT,
    A.INFOONLY
    from     BFLOG_AT A, BFLOG_ACCADDRESS B
    WHERE A.ACCADDRESSES = B.NAME
    AND A.STARTDATE >= :P63_START_DATE
    AND A.ENDDATE <= :P63_END_DATE
    --AND (A.EXERCISEAREAS LIKE "GAP, OA, OAL")
    --OR (A.EXERCISEAREAS LIKE "Harz")
    AND A.AUTHORISED = 1
    AND A.INFOONLY = 1' ;
    END IF;
    RETURN v_query;
    END;
    Cheers
    Gus

  • Unable to call a Packaged function in SQL statement??

    I have written a package & overloaded a function 3 times. I am using different parameter name for overloading & call as follows:
    my_pkg.ovrld_func(p_1 => v_val)
    my_pkg.ovrld_func(p_2 => v_val)
    my_pkg.ovrld_func(p_3 => v_val)
    When i use this statement in a sql or DML statement i get the following error.
    ORA-00907: missing right parenthesis
    I searched for limitations on packages but couldn't find this issue.
    FYI: I am using Oracle 9i Rel2
    Thanks

    I think its a bug as Oracle didn't report this limitation anywhere in the documentation & i should open a TAR.Well, it's documented limitation in fact.
    Quote "Oracle9i Application Developer’s Guide - Fundamentals Release 2 (9.2)"
    In a chapter entitled "Syntax for SQL Calling a PL/SQL Function"
    p. 9-53.
    Arguments
    To pass any number of arguments to a function, supply the arguments within the
    parentheses. You must use positional notation; named notation is not currently
    supported. For functions that do not accept arguments, use ().Regards.

  • Calling a R function from sql

    Hello there, can anyone help me on the following query ?
    1) I have a data view called Q_X1_V stored in a database schema, which has a column called OBS03
    2) I have logged in to the schema where the above mentioned view is defined using sqldeveloper
    3) I have created the following R function and executed in sql developer
    begin
       sys.rqScriptDrop('xbarr-qcc');
       sys.rqScriptCreate('xbarr-qcc', 'function() {
       library(ORE)
       ore.sync(table=Q_X1_V)
      ore.attach()
    dataset <- ore.pull(Q_X1_V["OBS03"])
    head(dataset)
    end;
    It has created the function successfully.
    4)  and I am trying to execute the following sql query in sql developer
    select *
    from table(rqEval(NULL,'select 1 "OBS03" from dual','xbarr-qcc'));
    and it results in the following error
    ORA-20000: RQuery error
    Error in .ore.schema(schema) : attempt to apply non-function
    ORA-06512: at "RQSYS.RQEVALIMPL", line 104
    ORA-06512: at "RQSYS.RQEVALIMPL", line 101
    20000. 00000 -  "%s"
    *Cause:    The stored procedure 'raise_application_error'
               was called which causes this error to be generated.
    *Action:   Correct the problem as described in the error message or contact
               the application administrator or DBA for more information.
    Not sure how to trouble shoot the issue
    5) Above R function mentioned in the step:3 works fine on the R command prompt
    and gives me the following output
    OBS03
    1 10.872
    2 10.818
    3 10.802
    4 10.622
    5 10.708
    6 10.658
    and how do I make the sql command mentioned in step:4 work in sqldeveloper command line.
    Any help is appreciated.
    thanks
    Pradeep

    Sherry,  thanks for the reply.
    1) I have logged into the database user via sqldeveloper as "ruser"
        and executed the following script for creating the R function
    begin
       sys.rqScriptDrop('xbarr-qcc');
       sys.rqScriptCreate('xbarr-qcc', 'function() {
       library(ORE)
    # ore.connect(user="ruser" ....   )  -- commented this out as I have already logged into the "ruser" schema of database
       ore.sync(table="Q_X1_V")    
       dataset <- ore.pull(Q_X1_V["OBS03"])  # pulling the data from the column OBS03 of the table. Q_X1_V
       dataset           #  simply return the rows
    end;
    2)  Now when I execute the following sql select command
    select *
      from table( rqEval(
            cursor(select 1 "ore.connect" from dual),      ## -- was hoping this will help me connect with the db schema.
            'select 1 "OBS03" from dual',
            'xbarr-qcc'));
    but I end up getting this error :
    ORA-20000: RQuery error
    Error in ore.pull(Q_X1_V["OBS03"]) :
      error in evaluating the argument 'x' in selecting a method for function 'ore.pull': Error: object 'Q_X1_V' not found
    ORA-06512: at "RQSYS.RQEVALIMPL", line 104
    ORA-06512: at "RQSYS.RQEVALIMPL", line 101
    20000. 00000 -  "%s"
    *Cause:    The stored procedure 'raise_application_error'
               was called which causes this error to be generated.
    *Action:   Correct the problem as described in the error message or contact
               the application administrator or DBA for more information.
    So what am I missing,
    1) I don't want to use ore.connect inside my R script because that will lead to security standards violations as the login credentials will be visible to all
    2) Once connected to the ruser, I should be able to run R script seemlessly with out passing in login credentials explicitly.
    which I thought  the sql script in step 2, with ore.connect in params should be helpful.   but for some reason it is erroring out.
    Could you pl. help.
    thanks

  • Calling SQL function in SQL query fails

    Hi There,
    I am trying to execute INSERT INTO XML_DATA (NAME, DATASIZE, DATA) VALUES (?,?,XMLType('?')) using ODBC C
    SQLBindParameter APIs.
    If I execute the INSERT INTO XML_DATA (NAME, DATASIZE, DATA) VALUES (?,?,XMLType('<name>milind</name>')) works fine.
    Can anybody please help me out here?
    Thanks,
    Milind
    /* blob.c
    * The following C code demonstrates how to read an input file, piecewise
    * (in chunks), and write it into a BLOB or LONG RAW column in the database.
    * It then reads that BLOB or LONG RAW data, piecewise, from the database
    * and writes it back to the OS as an output file that you specify.
    * Enter the following SQL statement via SQL*Plus to create the table
    * 'images_data' for use with this sample. Make sure you log into
    * Oracle as a user appropriate for running this example.
    * For BLOB, use the following table:
    * CREATE TABLE images_data (
    * name VARCHAR2(100),
    * imagesize NUMBER,
    * image BLOB);
    * For LONG RAW, use the following table:
    * CREATE TABLE images_data (
    * name VARCHAR2(100),
    * imagesize NUMBER,
    * image LONG RAW);
    * Change the connection information at the beginning of the procedure OpenOra
    * to your DSN, username and password.
    * To run this program, open a Command Prompt and use the following syntax:
    * Syntax: <program_name> <infile_name> <outfile_name>
    * Example call: C:\> blob my_photo.jpg copy_of_my_photo.jpg
    #include "stdafx.h"
    #include <stdio.h>
    #include <io.h>
    #ifndef NUTC
    #include <windows.h>
    #endif
    #include <sql.h>
    #include <sqlext.h>
    #ifdef NUTC
    #include <sys/types.h>
    #include <sys/stat.h>
    #endif
    * Global variables
    HENV hOdbcEnv = NULL; /* Environment handle */
    HDBC hDbConn = NULL; /* Connection handle */
    int sr; /* Return value */
    #define BUFSIZE 32020 /* Chunksize */
    * Connect routine
    void OpenOra()
    char szDSN[] = "XY10g2"; /* Data Source Name (DSN) */
    char szUID[] = "odbc1"; /* Username */
    char szAUTH[] = "pdmuser"; /* Password */
    * Allocate environment handle
    sr = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hOdbcEnv);
    if (sr != SQL_SUCCESS)
    printf ("Error allocating environment handle\n");
    * Set the ODBC Version
    sr = SQLSetEnvAttr(hOdbcEnv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
    if (sr != SQL_SUCCESS)
    printf ("Error setting ODBC version\n");
    * Allocate connection handle
    sr = SQLAllocHandle (SQL_HANDLE_DBC, hOdbcEnv, &hDbConn);
    if (sr != SQL_SUCCESS)
    printf ("Error allocating connection handle\n");
    * Connect
    sr = SQLConnect(hDbConn, (UCHAR *)szDSN, SQL_NTS,(UCHAR *)szUID, SQL_NTS, (UCHAR *)szAUTH, SQL_NTS);
    if (sr != SQL_SUCCESS)
    printf("Connection failed\n");
    * Disconnect routine
    void CloseOra()
    * Disconnect and free connection and environment handles
    sr = SQLDisconnect(hDbConn);
    if (hDbConn != SQL_NULL_HANDLE)
    SQLFreeHandle(SQL_HANDLE_DBC, hDbConn);
    if (hOdbcEnv != SQL_NULL_HANDLE)
    SQLFreeHandle(SQL_HANDLE_ENV, hOdbcEnv);
    * Read INFILE into the database and read data back out and save as OUTFILE.
    void readCertImage(char read_name, long filesize, char write_name)
    SQLCHAR iSqlCmd[300] = "INSERT INTO XML_DATA (NAME, DATASIZE, DATA) VALUES (?,?,XMLType('?'))";
    SQLCHAR iSqlCmd1[300] = "SELECT DATA FROM XML_DATA WHERE NAME = ?";
    FILE ifile, ofile; /* File pointers */
    time_t startTime, endTime;
    time_t startTimeIO, endTimeIO;
    int IOtime = 0;
    unsigned char buf[BUFSIZE]; /* Buffer to hold chunk */
    unsigned char buf1[BUFSIZE]; /* Buffer to hold chunk */
    SQLINTEGER type[3]; /* Type of data */
    SQLPOINTER pToken; /* Which column is piecewise */
    HSTMT hstmt = NULL; /* Statement handle */
    long i; /* Byte Counter */
    long count; /* Piecewise Counter */
    long rd; /* Amount to read */
    * Log on
    OpenOra();
    ifile = fopen(read_name, "r"); /* Open the file for reading in ASCII mode */
    * Allocate statement handle
    sr = SQLAllocHandle(SQL_HANDLE_STMT, hDbConn, &hstmt);
    if (sr != SQL_SUCCESS)
    printf("Error allocating statement handle\n");
    * Prepare insert statement
    sr = SQLPrepare(hstmt, iSqlCmd, SQL_NTS);
    if (sr != SQL_SUCCESS)
    printf("Error preparing insert statement\n");
    * Bind Parameters
    /* Name of BLOB */
    sr = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 0, 0,read_name, strlen(read_name), &type[0]);
    if (sr != SQL_SUCCESS)
    printf("Error binding name variable\n");
    /* Size of BLOB */
    sr = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_NUMERIC, 0, 0,&filesize, 0, &type[1]);
    if (sr != SQL_SUCCESS)
    printf("Error binding length variable\n");
    * As this will be a piecewise insert do not need to pass a buffer here.
    * Instead pass the parameter number for identification purposes.
    /* BLOB data */
    sr = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0,(SQLPOINTER)3, 0, &type[2]);
    if (sr != SQL_SUCCESS)
    printf("Error binding data variable\n");
    type[0] = SQL_NTS; /* Null terminated string */
    type[1] = 0; /* Ignored for numbers */
    type[2] = SQL_LEN_DATA_AT_EXEC(filesize); /* Data at execution time */
    time( &startTime );
    * Execute the insert
    sr = SQLExecute(hstmt);
    if (sr == SQL_NEED_DATA)
    printf("\nAbout to perform piecewise insert of data\n\n");
    else if (sr != SQL_SUCCESS)
    printf("Error executing insert statement\n");
    * Retrieve the pointer to the buffer containing the address
    * of the location where the source BLOB will be sent
    sr = SQLParamData(hstmt, &pToken);
    if (sr != SQL_NEED_DATA)
    printf("Error - no piecewise operations required\n");
    * Write the data in BUFSIZE chunks
    i = 0; /* Initialize bytes inserted
    count = 0; /* Initialize pieces/chunks inserted */
    do
    count++; /* Increment chunk number */
    * If remaining bytes to read is greater than BUFSIZE,
    * read another BUFSIZE chunk. Otherwise, read remaining
    * chunk of bytes (which will be less than BUFSIZE)
    if (filesize - i >= BUFSIZE)
    rd = BUFSIZE;
    else
    rd = (filesize - i);
    printf("%5ld:%10ld - About to write %ld bytes to the database\n",count,i,rd);
    * Reads one rd sized chunk of data into buffer from source file (BLOB)
    time( &startTimeIO );
    fread(buf, rd, 1, ifile);
    time( &endTimeIO );
    IOtime = IOtime + (endTimeIO - startTimeIO);
    * Sends the contents of the buffer to the ODBC driver
    SQLPutData(hstmt, buf, rd);
    /* Recalculate total bytes sent */
    if (filesize - i >= BUFSIZE)
    i+= BUFSIZE;
    else
    i+= (filesize - i);
    } while (i < filesize);
    /* Check to see if all data has been sent */
    sr = SQLParamData(hstmt, &pToken);
    if (sr == SQL_NEED_DATA)
    printf("Error - still need data\n");
    printf("%5ld:%10ld - Done writing data\n",++count,i);
    time( &endTime );
    printf("BLOB Write completed StartTime: %d, EndTime: %d, IOTime: %d in seconds.\n", endTime, startTime, IOtime);
    printf("BLOB Write completed in %d seconds.\n", (endTime - startTime) - IOtime);
    fclose(ifile); /* Close the INFILE */
    printf("\nData inserted into database\n\n");
    * Now read the data back. Reuse the previous statement handle.
    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
    sr = SQLAllocHandle(SQL_HANDLE_STMT, hDbConn, &hstmt);
    if (sr != SQL_SUCCESS)
    printf("Error allocating statement handle\n");
    * Prepare select statement, bind variable and execute
    sr = SQLPrepare(hstmt, iSqlCmd1, SQL_NTS);
    if (sr != SQL_SUCCESS)
    printf("Error preparing select statement\n");
    sr = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 0, 0, read_name, strlen(read_name), &type[0]);
    if (sr != SQL_SUCCESS)
    printf("Error binding name variable\n");
    time( &startTime );
    sr = SQLExecute(hstmt);
    if (sr != SQL_SUCCESS)
    printf ("Error executing insert statement\n");
    ofile = fopen(write_name, "w"); /* Open the file for writing in ASCII mode */
    sr = SQLFetch(hstmt);
    if (sr != SQL_SUCCESS)
    printf ("Error fetching data\n");
    * Read the data in BUFSIZE chunks.
    i = 0; /* Initialize bytes inserted */
    count = 0; /* Initialize pieces/chunks inserted */
    memset(buf, NULL, BUFSIZE);
    do
    * Retrieve a BUFSIZE chunk of data into the buffer
    sr = SQLGetData(hstmt, 1, SQL_C_CHAR, buf, BUFSIZE, &type[2]);
    if (sr == SQL_ERROR)
    printf("Error fetching data\n");
    break;
    time( &startTimeIO );
    count++; /* Increment chunk number */
    /* Determine if this is a full chunk or the last chunk */
    if (filesize - i >= BUFSIZE)
    printf("%5ld:%10ld - About to write %ld bytes to file\n",count,i,BUFSIZE);
    fwrite(buf, BUFSIZE, 1, ofile); /* Write BUFSIZE chunk to file */
    else
    printf("%5ld:%10ld - About to write %ld bytes to file\n",count,i,filesize-i);
    fwrite(buf, filesize-i, 1, ofile); /* Write remaining chunk to file */
    time( &endTimeIO );
    IOtime = IOtime + (endTimeIO - startTimeIO);
    /* Recalculate total bytes retrieved */
    if (filesize - i >= BUFSIZE)
    i+= BUFSIZE;
    else
    i+= (filesize - i);
    } while (sr == SQL_SUCCESS_WITH_INFO);
    printf("%5ld:%10ld - Done writing file\n",++count,i);
    time( &endTime );
    printf("BLOB Read completed StartTime: %d, EndTime: %d, IOTime: %d in seconds.\n", endTime, startTime, IOtime);
    printf("BLOB Read completed in %d seconds.\n", (endTime - startTime) - IOtime);
    fclose(ofile); /* Close the OUTFILE */
    printf("\nData written to file\n");
    * Log off
    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
    CloseOra();
    * Main routine
    void main(argc, argv)
    int argc; /* Number of command line arguments */
    char argv[]; / Array of command line arguments */
    long filesize = 0; /* Size of INFILE */
    FILE ifile; / Pointer to INFILE */
    #ifdef NUTC
    struct stat statbuf; /* Information on a file. */
    #endif
    /* Check for the proper number of command line arguments entered by user */
    if (argc != 3)
    printf("\nCommand line syntax: <program_name> <infile_name> <outfile_name>");
    printf("\n Example call: blob input.exe output.exe\n");
    exit(1);
    /* Open INFILE */
    if( (ifile = fopen(argv[1], "rb" )) == NULL )
    printf( "\nThe file '%s' could not be opened\n",argv[1]);
    exit(1);
    else
    printf( "\nThe file '%s' was opened successfully\n",argv[1]);
    #ifdef NUTC
    /* Determine length of the INFILE */
    if (fstat(fileno(ifile), &statbuf) == 0)
    filesize = statbuf.st_size;
    else
    filesize = 0;
    #else
    filesize = filelength(fileno(ifile));
    #endif
    printf( "The file is %d bytes long\n",filesize);
    /* Close INFILE */
    fclose(ifile);
    /* Insert and retrieve BLOB */
    readCertImage(argv[1], filesize, argv[2]);
    }

    During binding, strings are generally skipped. As such, you should first try replacing XMLType('?') with XMLType(?). You don't need to specify '?' because the system knows the proper type from your SQLBindParameter call.
    Also, you should try replacing:
    sr = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0,(SQLPOINTER)3, 0, &type[2]);
    with
    sr = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0,(SQLPOINTER)buf, BUFSIZE, &type[2]);

  • APEX, BI Publisher and SQL Query (PL/SQL Function returning SQL Query)..

    I don't know if I should be posting this in this Forum or the BI Publisher forum, so I am posting in BOTH forums..
    I love APEX, let me say that first.. And appreciate the support offered here by the group, but am running int a confusing issue when BI Publisher tries to build a report from the above type APEX report..
    Here is my dilemma:
    I have a number of reports that are part of a Oracle package. They return an SQL Query back to a reports region on a page. I am having to deal with the column names returned are col01, col02..
    The issue I have is, when building the Application Level query to download the XML sample from in building RTF layouts in Word, you can not use this code, you MUST use a standard SQL Select.
    I have taken the sql from the function returning sql, and copied into the application query, supplying the required data values for bind variables being used in the query.
    An XML file is produced, and I use this to build the RTF format file that I load back into APEX and try to use it for the PDF rendering of the report. I can view the output as a PDF in the Word add on, but when I try using it with the report, it is returning an empty PDF file.
    Can anyone tell me what error log files on the bi publisher side I can look at to see what error is happening?
    Thank you,
    Tony Miller
    UTMB/EHN
    Title changed, maybe SOMEONE has an idea on this??
    Message was edited by:
    Tony Miller

    Hi,
    1/ first check you are passing the bind variables and
    appropriate values in the call to your report - if
    the query returns no data then you get an empty page
    So if your query takes :P10_USERNAME variable then
    pass it to the report in the URL
    f?p=&APP_ID.:0:&SESSION.:PRINT_REPORT=YOUR_REP_QUERY_N
    AME:::P10_USERNAME:MYUSER
    2/ try to use the Default layout first to check your
    report query really returns the data when called
    3/ if you defined a header in your rtf template check
    there is no & (ampersand) - if using & in the header
    and preview the template from word it displays data
    OK, but if you use this template in the report query
    it fails to render the data (bug in Apex-> Bi
    Publisher integration maybe?)
    4/ If using the table in the rtf template check its
    width does not overflow the page margins - there is a
    problem with pdf export
    5/ check
    /oc4j/j2ee/home/application-deployments/xmlpserver/app
    lication.log forthe information on BI Publisher runs
    RadoIssue was in the APEX page having issues.. I recoded a new page and am able to generate BI Publisher based PDF files..
    Thank you,
    Tony Miller
    UTMB/EHN

  • Demonstrating PL/SQL Functions Using SQL Developer

    Good afternoon,
    I'm starting to write some PL/SQL functions to replace some of the SQL that I use most frequently.  A couple of very simple examples would be:
    create or replace function func_test (p_1 number) return number
    is
    x number;
    y number;
    begin
    x :=1;
    y :=2;
    return p_1 * x * y;
    end func_test;
    create or replace function func_test2 (p_1 varchar2) return varchar2
    is
    return_val varchar2(10);
    begin
    select p_1 into return_val from dual;
    return return_val;
    end func_test2;
    However, at my workplace I haven't been granted create function privileges yet until I can demonstrate some examples, which is understandable.
    For the time being, without these privileges, is there a way I can build/test functions in principle locally using SQL Developer without the need to write the functions to our database? I.e. can I demonstrate the above in SQL Developer, but without wrapping in create or replace syntax?
    I hope this isn't too vague.
    Using Oracle 11gR2 (not logged in to workplace database at the moment for specific version no.)
    SQL Developer 3.4
    Thanks,
    TP

    sb92075 02-Nov-2013 19:12 (in response to TinyPenguin)
    populating test DB with data is a solvable problem.
    You don't need client data to test code (functions).
    You only need sample test data; which generally is less than a few dozen records per table.
    Absolutely, of course. Our client database is pretty messy though, and includes data prior to the implementation of more recent business rules that I need to take account of. Useful perspective though, thanks.
    rp0428 02-Nov-2013 19:14 (in response to TinyPenguin)
    Sure, but then I wouldn't have access to all the data in our client database to test functions under various circumstances.
    Huh? Why not? It's your database so what keeps you from creating a database link to your client database where all the data is?
    Also, I suppose it's not good practice to constantly write/replace/drop functions to/from a database when developing them? Better to test the function in principle and then write to the database?
    Huh? Why not? What you think a dev database is for if not for development?
    Based on your two posts so far in this thread it's understandable why they don't want to give you privileges yet. Those sample 'functions' you posted are NOT a good use for functions.
    In sql developer you can just create and save the queries you use most often. There is no need to create functions for that.
    But if you do need an anonymous function now and then just create one using sql*plus syntax:
    Our IT department are pretty sensitive about how they allow access, even to the dev environment. As you've identified, I'm not naturally a programmer so the option to play around with the data to develop some representative examples about how we can simplify and devolve SQL reporting to more members of staff is useful to me. I just wrote those two function quickly for the purpose of posting some sample data, which I thought would be helpful. Thanks for illustrating how to return their output using an anonymous block.
    FrankKulash 02-Nov-2013 19:13 (in response to TinyPenguin)
    Hi,
    The obvious solution is to get the privileges.  If your employer really wants you to do something, they need to give you the necessary privileges to do it.  It's silly for them to tell you to do something, but refuse to let you do it.
    Failing that, you can install Oracle on your own machine, as suggested above.  It's free and legitimate if you're only using it for learning and developing.  Oracle Express Edition is very easy to install.
    As a last resort, you can write functions and procedures that are local to an anonymous block, like this:
    Thanks Frank. Yeah I'm going to speak with our DBA next week about privileges. I've got XE/SQL Developer installed on my own computer - I wrote those sample functions using them - I just wasn't sure how to call/return anonymous blocks as both you and rp identified to develop at work as an interim solution.
    Thanks a lot All,
    TP.

  • Conditional display of region with PL/SQL function returning SQL query

    Hello,
    ApEx 2.0.
    I use PL/SQL functions that return SQL queries to display the contents of a region.
    How could I conditionally display such region ? If no data is found, the region shouldn't be shown. I tried with "SQL query returns at least one row" but this doesn't seem to work.
    Thanks,
    Matthias

    Hi Matthias,
    Are the regions in question report regions? So your PL/SQL process is returning a SQL query and then populating a report?
    The EXISTS(SQL Query returns at least one row) condition should work, try running the query you are using in the Expression 1 textarea inside SQL*Plus, or SQL developer using the same parameters, and see what gets returned.
    If you are still stuck, can you post the query you are using inside your Expression 1 textarea of the Conditions section and I can take a look at it for you.
    Hope this helps,
    Cj

  • How do I test sql function in sql*plus?

    Hi,
    I was given the syntax for a sql function and need to test this in SQL*Plus. What syntax do I use to test this?
    p_UserName IN OUT SMUser.Name%type,p_PW IN OUT SMUser.
    Password%type) RETURN INTEGER IS
    nRet INTEGER :=1;
    nCount NUMBER := 0;
    BEGIN
    select count(*) into nCount from smUser where smUser.Name = p_UserName
    and smUser.Password = p_PW;
    IF (nCount = 1) THEN
    SELECT smUser.Name into p_UserName from smUser where smUser.Name =
    p_UserName and smUser.Password = p_PW;
    SELECT smUser.Password into p_PW from smUser where smUser.Name =
    p_UserName and smUser.Password = p_PW;
    RETURN 0;
    END IF;
    RETURN nRet;
    END paulsoraclefunction;
    Thanks,
    Paul

    This should work. You will need to make sure that the variables are declared as the same data type as in the function. Unfortunately, you cannot use %TYPE in declaring SQL*Plus variables.
    VARIABLE p_username VARCHAR2(30);
    VARIABLE p_pw VARCHAR2(30);
    BEGIN
    :p_username := 'PAUL';
    END;
    SELECT paulsoraclefunction(:p_username,:p_pw) FROM dual;
    SELECT :p_username,:p_pw FROM dual;
    TTFN
    John

  • Using a PL/SQL function in SQL

    Hello
    I wrote a function in pl/sql that create a table and return the name of the table as varchar2.
    The function is AUTONOMOUS TRANSACTION.
    I want to write a SQL that in the �FROM� section will call the function.
    The SQL will take the name of the table (from the function) and recognize it as a table.
    That way I can preform a join between the new table and other tables.
    Do you know on a way to preform that?
    I wrote the following SQL:
    (assume the name of the function is � �New_table()� return varchar2 )
    Select *
    From (select �New_Table()� from dual) ;
    This return the name of the table. But I want a SQL that will bring the data from the table
    Apreciate your help
    Hilit

    You say "I wrote a function in pl/sql that create a table and return the name of the table as varchar2.", now you want to select data from the newly created table in the same sql statement?
    Although you could cobble something together in PL/SQL using EXECUTE IMMEDIATE, or in a sql script using several statements that would work, where will the data come from?
    I'm guessing that you are populating the table in the function and are hoping to use it as something similar to a temp table in Sybase/SqlServer. If so, there are almost certainly several better ways to do this in Oracle.
    Why don't you tell us what you are trying to accomplish by building a table in the FROM clause of a sql statement, and maybe someone can give a better solution.
    TTFN
    John

  • Creating PL/SQL function in SQL plus which will display desired output

    Hello PL/SQL experts,
    I am not skilled on PL/SQL so want you help for one of the PL/SQL requirement.
    Requirement: We have a database purge jobs which deletes the records from our application database on daily basis. Our Client wants a verification PL/SQL to be created which they will run pre and post the purge job to identify the number of records deleted/processed by purge job. It should do a SELECT operation and find out the number of records in table based on the where clause and give the output to the user.
    The result of PL/SQL should be something like this (considering the PL/SQL is processing multiple select statements):
    ****Verification SQL Start*****
    30 records from table S_SRV_REQUEST selected
    45 records from table S_SRV_REQUEST_X selected
    15 records from table S_SRV_REQUEST_XM selected
    *****Verification SQL complete*****
    For this I am thinking of a simple PL/SQL which will diplay the count of records from each table but I am not sure how to display the count on screen as an output. Can I request PL/SQL experts to put some light on this?
    Regards
    Sumit

    PL/SQL is a server side process running on your database server.  It is not connected to a display or a keyboard, so cannot output any results from within the code itself.
    What you need is a client application that the user can run which will query the database, or call procedure(s) to get results and then the client application will display those results appropriately.
    One of the simplest client tools you can use to build such a user-friendly application is Oracle Application Express (APEX).
    Bear in mind that if you're going to 'identify' record for deletion prior to actually deleting them, then you may also have a need to store the keys of those identified records somewhere so that only those records are deleted.  Consider the situation where the user requests the information and the application queries the records to say there are 30 records from S_SRV_REQUEST with the correct criteria to be deleted.  By the time the user confirms they are happy and want the records deleted, some other record(s) may have been updated and also meet the criteria, so just doing a delete based on the criteria itself could result in more than 30 records being deleted.  However if you've identified the records and marked them in some way for deletion or stored the keys of those records on a queue somewhere to indicate the ones to be deleted, then your actual deletion process can just deal with those records and ignore any that have met the criteria since that time.  Of course that depends on your individual requirements, but it's something to bear in mind.

Maybe you are looking for