string m_InUserName='秋天玫瑰',m_out_password
SQLCA.AutoCommit = True
DECLARE abc_proc PROCEDURE FOR abc @a = :m_InUserName;
EXECUTE abc_proc;
Fetch abc_proc into :m_out_password;
messagebox(string(m_out_password),string(m_out_password));
错误提示是:对于造型说明无效的字符值.
7 个解决方案
#1
参数@a在存储过程这边是char(8)类型的.怎么办?
#2
In addition to result sets, Sybase Systems 10.x and 11.x stored procedures may return a long integer return value and output parameters of any data type. After all of the result sets have been returned, PowerScript requires you to issue one final FETCH procedure_name INTO . . . statement to obtain these values. The order in which these values are returned is:
return value, output parm1, output parm2, ...
Example 1
The following stored procedure contains one input parameter (@deptno) and returns a result set containing employee names and salaries for that department. It also returns two output parameters (@totsal and @avgsal), and a return value that is the count of employees in the department.
CREATE PROCEDURE deptroster @deptno integer,
@totsal double precision output,
@avgsal double precision output
AS
DECLARE @number_of_emps integer
SELECT emp_fname, emp_lname, salary FROM employee
WHERE dept_id = @deptno
SELECT @totsal = sum(salary),
@avgsal = avg(salary),
@number_of_emps = COUNT(*) FROM employee
WHERE dept_id = @deptno
RETURN @number_of_emps;
Example 2
The following PowerScript code fragment declares and executes the deptroster stored procedure, processes the result set, and then fetches the return value and output parameters.
integer fetchcount = 0
long lDeptno, rc
string fname, lname
double dSalary, dTotSal, dAvgSal
lDeptno = 100
DECLARE deptproc PROCEDURE FOR
@rc = dbo.deptroster
@deptno = :lDeptno,
@totsal = 0 output,
@avgsal = 0 output
USING SQLCA;
EXECUTE deptproc;
CHOOSE CASE SQLCA.sqlcode
CASE 0
// Execute successful. There is at least one
// result set. Loop to get the query result set
// from the table SELECT.
DO
FETCH deptproc INTO :fname, :lname, :dSalary;
CHOOSE CASE SQLCA.sqlcode
CASE 0
fetchcount++
CASE 100
MessageBox ("End of Result Set", &
string (fetchcount) " rows fetched")
CASE -1
MessageBox ("Fetch Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
LOOP WHILE SQLCA.sqlcode = 0
// Issue an extra FETCH to get the Return Value
// and Output Parameters.
FETCH deptproc INTO :rc, :dTotSal, :dAvgSal;
CHOOSE CASE SQLCA.sqlcode
CASE 0
MessageBox ("Fetch Return Value and Output" &
"Parms SUCCESSFUL", "Return Value is: " &
string (rc) &
"~r~nTotal Salary: " string (dTotSal) &
"~r~nAverage Sal: " string (dAvgSal))
CASE 100
MessageBox ("Return Value and Output Parms" &
"NOT FOUND", "")
CASE ELSE
MessageBox ("Fetch Return Value and Output" &
"Parms FAILED", "SQLDBCode is " &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
CLOSE deptproc;
CASE 100
// Execute successful; no result set.
// Do not try to close.
MessageBox ("Execute Successful", "No result set")
CASE ELSE
MessageBox ("Execute Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
return value, output parm1, output parm2, ...
Example 1
The following stored procedure contains one input parameter (@deptno) and returns a result set containing employee names and salaries for that department. It also returns two output parameters (@totsal and @avgsal), and a return value that is the count of employees in the department.
CREATE PROCEDURE deptroster @deptno integer,
@totsal double precision output,
@avgsal double precision output
AS
DECLARE @number_of_emps integer
SELECT emp_fname, emp_lname, salary FROM employee
WHERE dept_id = @deptno
SELECT @totsal = sum(salary),
@avgsal = avg(salary),
@number_of_emps = COUNT(*) FROM employee
WHERE dept_id = @deptno
RETURN @number_of_emps;
Example 2
The following PowerScript code fragment declares and executes the deptroster stored procedure, processes the result set, and then fetches the return value and output parameters.
integer fetchcount = 0
long lDeptno, rc
string fname, lname
double dSalary, dTotSal, dAvgSal
lDeptno = 100
DECLARE deptproc PROCEDURE FOR
@rc = dbo.deptroster
@deptno = :lDeptno,
@totsal = 0 output,
@avgsal = 0 output
USING SQLCA;
EXECUTE deptproc;
CHOOSE CASE SQLCA.sqlcode
CASE 0
// Execute successful. There is at least one
// result set. Loop to get the query result set
// from the table SELECT.
DO
FETCH deptproc INTO :fname, :lname, :dSalary;
CHOOSE CASE SQLCA.sqlcode
CASE 0
fetchcount++
CASE 100
MessageBox ("End of Result Set", &
string (fetchcount) " rows fetched")
CASE -1
MessageBox ("Fetch Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
LOOP WHILE SQLCA.sqlcode = 0
// Issue an extra FETCH to get the Return Value
// and Output Parameters.
FETCH deptproc INTO :rc, :dTotSal, :dAvgSal;
CHOOSE CASE SQLCA.sqlcode
CASE 0
MessageBox ("Fetch Return Value and Output" &
"Parms SUCCESSFUL", "Return Value is: " &
string (rc) &
"~r~nTotal Salary: " string (dTotSal) &
"~r~nAverage Sal: " string (dAvgSal))
CASE 100
MessageBox ("Return Value and Output Parms" &
"NOT FOUND", "")
CASE ELSE
MessageBox ("Fetch Return Value and Output" &
"Parms FAILED", "SQLDBCode is " &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
CLOSE deptproc;
CASE 100
// Execute successful; no result set.
// Do not try to close.
MessageBox ("Execute Successful", "No result set")
CASE ELSE
MessageBox ("Execute Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
#3
:lDeptno参数为char型怎么办?
#4
string 就可以!
#5
声明并执行Oracle存储过程及函数
This document contains an example that creates a stored procedure dynamically with two input arguments and two output arguments.
Overview
This document provides examples of Oracle functions and stored procedures along with the script used to declare and execute them within PowerBuilder. The Powerscript syntax is valid for PowerBuilder 6, 7 and 8. There is a companion PBL is in the PowerBuilder Samples library in the software downloads. that contains the examples. This PBL is written in PowerBuilder 7.
Stored Procedure/Package Synonyms
Oracle 7 Behavior
The Oracle 7 OCI calls that describe stored procedures resolve PUBLIC and private synonyms to correctly describe the procedure. The behavior is similar to the way SQL*Plus resolves the name if you enter "Execute myproc". It first checks to see if you own a stored procedure called "myproc". Failing that, it checks to see if you own a private synonym called "myproc". Failing that, it checks to see if there is a PUBLIC synonym called "myproc".
Oracle 8 Behavior
Oracle changed the OCI calls between Oracle 7 and Oracle 8. Oracle 8 requires a fully qualified object name in the describe call. This is a problem because Powerscript that compiled and worked with the PowerBuilder native drivers for Oracle 7 may now fail at compilation or execution with the native drivers for Oracle 8.
For Example, if you create a public synonym (syn_pkg) for a package that contains stored procedure my_proc, you could reference the procedure as syn_pkg.my_proc when using the native driver for Oracle 7. However, this will cause a script compilation error with Oracle 8. You must change the reference to "PUBLIC".syn_pkg.myproc to make it work. PowerBuilder 7 and higher contain an enhancement that will resolve this behavior internally, which means that either format will work.
If you put quotes around the stored procedure name, the procedure name must be upper-case.
Stored Procedures using DBLink
Overview
The DBLink feature in Oracle allows access to objects on a different Oracle instance than the one you are connected to. Calls are passed to the linked server and, from the client perspective, it all looks like it is coming from the same server.
Oracle 7 Behavior
The PowerBuilder native drivers for Oracle 7 use the OCI odessp() function to describe stored procedures. This function does not support procedures that use a database links whether they are expressed explicitly or by using synonyms. This implies that you cannot use stored procedures across database links in PowerBuilder. The only exception to this rule is that you can specify and RPC declaration for a procedure across a database link as long as it does not contain any PL/SQL table arguments. This will work because the arguments are described in the RPC declaration and no call to odessp() is needed.
Oracle 8 Behavior
Execution of stored procedures / functions are not supported.
Oracle Function Example
Consider the Oracle function declared as follows:
CREATE OR REPLACE FUNCTION system.func_get_empname (
arg_emp_id IN NUMBER) RETURN VARCHAR2 AS
l_lname VARCHAR2(20);
l_fname VARCHAR2(20);
l_name VARCHAR2(42);
BEGIN
SELECT last_name, first_name
INTO l_lname, l_fname
FROM demo.employee
WHERE employee_id = arg_emp_id;
IF SQLCODE <> 0 THEN
l_name := '*** name error ***';
ELSE
l_name := RTRIM(l_lname)||', '||RTRIM(l_fname);
END IF;
RETURN l_name;
END func_get_empname;
This function takes an employee ID as the single input argument and returns the employee name formatted as last name, comma, first name. If a select error occurs, the function returns an error in the return argument.
There are several ways to access this function from PowerBuilder. The following examples show the syntax for each of the methods.
Function called with Powerscript select
The following script shows how to treat the function like an Oracle system function and call it within a Powerscript SELECT INTO statement:
integer l_emp_id = 7555
string l_name
Select func_get_empname(:l_emp_id)
into :l_name
from dual
using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Select Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
This document contains an example that creates a stored procedure dynamically with two input arguments and two output arguments.
Overview
This document provides examples of Oracle functions and stored procedures along with the script used to declare and execute them within PowerBuilder. The Powerscript syntax is valid for PowerBuilder 6, 7 and 8. There is a companion PBL is in the PowerBuilder Samples library in the software downloads. that contains the examples. This PBL is written in PowerBuilder 7.
Stored Procedure/Package Synonyms
Oracle 7 Behavior
The Oracle 7 OCI calls that describe stored procedures resolve PUBLIC and private synonyms to correctly describe the procedure. The behavior is similar to the way SQL*Plus resolves the name if you enter "Execute myproc". It first checks to see if you own a stored procedure called "myproc". Failing that, it checks to see if you own a private synonym called "myproc". Failing that, it checks to see if there is a PUBLIC synonym called "myproc".
Oracle 8 Behavior
Oracle changed the OCI calls between Oracle 7 and Oracle 8. Oracle 8 requires a fully qualified object name in the describe call. This is a problem because Powerscript that compiled and worked with the PowerBuilder native drivers for Oracle 7 may now fail at compilation or execution with the native drivers for Oracle 8.
For Example, if you create a public synonym (syn_pkg) for a package that contains stored procedure my_proc, you could reference the procedure as syn_pkg.my_proc when using the native driver for Oracle 7. However, this will cause a script compilation error with Oracle 8. You must change the reference to "PUBLIC".syn_pkg.myproc to make it work. PowerBuilder 7 and higher contain an enhancement that will resolve this behavior internally, which means that either format will work.
If you put quotes around the stored procedure name, the procedure name must be upper-case.
Stored Procedures using DBLink
Overview
The DBLink feature in Oracle allows access to objects on a different Oracle instance than the one you are connected to. Calls are passed to the linked server and, from the client perspective, it all looks like it is coming from the same server.
Oracle 7 Behavior
The PowerBuilder native drivers for Oracle 7 use the OCI odessp() function to describe stored procedures. This function does not support procedures that use a database links whether they are expressed explicitly or by using synonyms. This implies that you cannot use stored procedures across database links in PowerBuilder. The only exception to this rule is that you can specify and RPC declaration for a procedure across a database link as long as it does not contain any PL/SQL table arguments. This will work because the arguments are described in the RPC declaration and no call to odessp() is needed.
Oracle 8 Behavior
Execution of stored procedures / functions are not supported.
Oracle Function Example
Consider the Oracle function declared as follows:
CREATE OR REPLACE FUNCTION system.func_get_empname (
arg_emp_id IN NUMBER) RETURN VARCHAR2 AS
l_lname VARCHAR2(20);
l_fname VARCHAR2(20);
l_name VARCHAR2(42);
BEGIN
SELECT last_name, first_name
INTO l_lname, l_fname
FROM demo.employee
WHERE employee_id = arg_emp_id;
IF SQLCODE <> 0 THEN
l_name := '*** name error ***';
ELSE
l_name := RTRIM(l_lname)||', '||RTRIM(l_fname);
END IF;
RETURN l_name;
END func_get_empname;
This function takes an employee ID as the single input argument and returns the employee name formatted as last name, comma, first name. If a select error occurs, the function returns an error in the return argument.
There are several ways to access this function from PowerBuilder. The following examples show the syntax for each of the methods.
Function called with Powerscript select
The following script shows how to treat the function like an Oracle system function and call it within a Powerscript SELECT INTO statement:
integer l_emp_id = 7555
string l_name
Select func_get_empname(:l_emp_id)
into :l_name
from dual
using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Select Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
#6
Function called using Remote Procedure Call (RPC)
If your stored procedure or function can be called as a remote Procedure Call (RPC), you will create less code and get better performance by using RPC's. The performance gain comes from the fact that the argument types are already known from the declaration so a costly describe is avoided. PowerBuilder generates the following Local External Function declaration for our example:
function string FUNC_GET_EMPNAME(double ARG_EMP_ID) RPCFUNC ALIAS FOR "~"SYSTEM~".~"FUNC_GET_EMPNAME~""
The code to call the function as an RPC follows:
integer l_emp_id = 7555
string l_name
l_name = sqlca.func_get_empname(l_emp_id)
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
Function called using Powerscript declare and execute
The code to call the function using the Powerscript DECLARE and EXECUTE follows :
integer l_emp_id = 7555
string l_name
declare sp_1 procedure for FUNC_GET_EMPNAME (:l_emp_id) using sqlca;
execute sp_1;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure execute error", sqlca.sqlerrtext)
return
end if
FETCH sp_1 into :l_name;
if sqlca.sqlcode = 0 then
MessageBox("Employee Name", l_name)
else
MessageBox("SQlCode", string(sqlca.sqlcode))
end if
close sp_1;
return
Example Function called with dynamic SQL Format 2
integer l_emp_id = 7555
string l_name
l_name = space(42)
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "select FUNC_GET_EMPNAME(?) from dual" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1 using :l_emp_id;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
end if
fetch sp_1 into :l_name;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Fetch Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
close sp_1;
return
Oracle SP with no argument or result set
The following stored procedure has no arguments and produces no result set. The success or failure information is returned in the SQLDBCode.
CREATE OR REPLACE PROCEDURE system.sp_test_noargs AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Test from sp_test_noargs');
if SQLCODE <> 0 then
RAISE_APPLICATION_ERROR(-20001, 'SQLCODE from put_line was '||TO_CHAR(SQLCODE));
end if;
END sp_test_noargs;
Powerscript Declare and Execute Example
integer l_emp_id = 7555
declare sp_1 procedure for SP_TEST_NOARGS using sqlca;
execute sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure execute error", string(sqlca.sqlcode) + ": " + string(sqlca.sqldbcode) + ": " + sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", sqlca.sqldbcode)
end if
close sp_1;
return
RPC example
Following is the RPC declaration for the stored procedure:
subroutine SP_TEST_NOARGS() RPCFUNC ALIAS FOR SYSTEM.SP_TEST_NOARGS
Following is the Powerscript to execute the stored procedure:
sqlca.sp_test_noargs()
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("RPC Call", "Successful")
end if
return
Powerscript Dynamic execution example
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "execute sp_test_noargs" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", "OK")
end if
close sp_1;
return
If your stored procedure or function can be called as a remote Procedure Call (RPC), you will create less code and get better performance by using RPC's. The performance gain comes from the fact that the argument types are already known from the declaration so a costly describe is avoided. PowerBuilder generates the following Local External Function declaration for our example:
function string FUNC_GET_EMPNAME(double ARG_EMP_ID) RPCFUNC ALIAS FOR "~"SYSTEM~".~"FUNC_GET_EMPNAME~""
The code to call the function as an RPC follows:
integer l_emp_id = 7555
string l_name
l_name = sqlca.func_get_empname(l_emp_id)
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
Function called using Powerscript declare and execute
The code to call the function using the Powerscript DECLARE and EXECUTE follows :
integer l_emp_id = 7555
string l_name
declare sp_1 procedure for FUNC_GET_EMPNAME (:l_emp_id) using sqlca;
execute sp_1;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure execute error", sqlca.sqlerrtext)
return
end if
FETCH sp_1 into :l_name;
if sqlca.sqlcode = 0 then
MessageBox("Employee Name", l_name)
else
MessageBox("SQlCode", string(sqlca.sqlcode))
end if
close sp_1;
return
Example Function called with dynamic SQL Format 2
integer l_emp_id = 7555
string l_name
l_name = space(42)
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "select FUNC_GET_EMPNAME(?) from dual" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1 using :l_emp_id;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
end if
fetch sp_1 into :l_name;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Fetch Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
close sp_1;
return
Oracle SP with no argument or result set
The following stored procedure has no arguments and produces no result set. The success or failure information is returned in the SQLDBCode.
CREATE OR REPLACE PROCEDURE system.sp_test_noargs AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Test from sp_test_noargs');
if SQLCODE <> 0 then
RAISE_APPLICATION_ERROR(-20001, 'SQLCODE from put_line was '||TO_CHAR(SQLCODE));
end if;
END sp_test_noargs;
Powerscript Declare and Execute Example
integer l_emp_id = 7555
declare sp_1 procedure for SP_TEST_NOARGS using sqlca;
execute sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure execute error", string(sqlca.sqlcode) + ": " + string(sqlca.sqldbcode) + ": " + sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", sqlca.sqldbcode)
end if
close sp_1;
return
RPC example
Following is the RPC declaration for the stored procedure:
subroutine SP_TEST_NOARGS() RPCFUNC ALIAS FOR SYSTEM.SP_TEST_NOARGS
Following is the Powerscript to execute the stored procedure:
sqlca.sp_test_noargs()
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("RPC Call", "Successful")
end if
return
Powerscript Dynamic execution example
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "execute sp_test_noargs" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", "OK")
end if
close sp_1;
return
#7
Fetch
#1
参数@a在存储过程这边是char(8)类型的.怎么办?
#2
In addition to result sets, Sybase Systems 10.x and 11.x stored procedures may return a long integer return value and output parameters of any data type. After all of the result sets have been returned, PowerScript requires you to issue one final FETCH procedure_name INTO . . . statement to obtain these values. The order in which these values are returned is:
return value, output parm1, output parm2, ...
Example 1
The following stored procedure contains one input parameter (@deptno) and returns a result set containing employee names and salaries for that department. It also returns two output parameters (@totsal and @avgsal), and a return value that is the count of employees in the department.
CREATE PROCEDURE deptroster @deptno integer,
@totsal double precision output,
@avgsal double precision output
AS
DECLARE @number_of_emps integer
SELECT emp_fname, emp_lname, salary FROM employee
WHERE dept_id = @deptno
SELECT @totsal = sum(salary),
@avgsal = avg(salary),
@number_of_emps = COUNT(*) FROM employee
WHERE dept_id = @deptno
RETURN @number_of_emps;
Example 2
The following PowerScript code fragment declares and executes the deptroster stored procedure, processes the result set, and then fetches the return value and output parameters.
integer fetchcount = 0
long lDeptno, rc
string fname, lname
double dSalary, dTotSal, dAvgSal
lDeptno = 100
DECLARE deptproc PROCEDURE FOR
@rc = dbo.deptroster
@deptno = :lDeptno,
@totsal = 0 output,
@avgsal = 0 output
USING SQLCA;
EXECUTE deptproc;
CHOOSE CASE SQLCA.sqlcode
CASE 0
// Execute successful. There is at least one
// result set. Loop to get the query result set
// from the table SELECT.
DO
FETCH deptproc INTO :fname, :lname, :dSalary;
CHOOSE CASE SQLCA.sqlcode
CASE 0
fetchcount++
CASE 100
MessageBox ("End of Result Set", &
string (fetchcount) " rows fetched")
CASE -1
MessageBox ("Fetch Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
LOOP WHILE SQLCA.sqlcode = 0
// Issue an extra FETCH to get the Return Value
// and Output Parameters.
FETCH deptproc INTO :rc, :dTotSal, :dAvgSal;
CHOOSE CASE SQLCA.sqlcode
CASE 0
MessageBox ("Fetch Return Value and Output" &
"Parms SUCCESSFUL", "Return Value is: " &
string (rc) &
"~r~nTotal Salary: " string (dTotSal) &
"~r~nAverage Sal: " string (dAvgSal))
CASE 100
MessageBox ("Return Value and Output Parms" &
"NOT FOUND", "")
CASE ELSE
MessageBox ("Fetch Return Value and Output" &
"Parms FAILED", "SQLDBCode is " &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
CLOSE deptproc;
CASE 100
// Execute successful; no result set.
// Do not try to close.
MessageBox ("Execute Successful", "No result set")
CASE ELSE
MessageBox ("Execute Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
return value, output parm1, output parm2, ...
Example 1
The following stored procedure contains one input parameter (@deptno) and returns a result set containing employee names and salaries for that department. It also returns two output parameters (@totsal and @avgsal), and a return value that is the count of employees in the department.
CREATE PROCEDURE deptroster @deptno integer,
@totsal double precision output,
@avgsal double precision output
AS
DECLARE @number_of_emps integer
SELECT emp_fname, emp_lname, salary FROM employee
WHERE dept_id = @deptno
SELECT @totsal = sum(salary),
@avgsal = avg(salary),
@number_of_emps = COUNT(*) FROM employee
WHERE dept_id = @deptno
RETURN @number_of_emps;
Example 2
The following PowerScript code fragment declares and executes the deptroster stored procedure, processes the result set, and then fetches the return value and output parameters.
integer fetchcount = 0
long lDeptno, rc
string fname, lname
double dSalary, dTotSal, dAvgSal
lDeptno = 100
DECLARE deptproc PROCEDURE FOR
@rc = dbo.deptroster
@deptno = :lDeptno,
@totsal = 0 output,
@avgsal = 0 output
USING SQLCA;
EXECUTE deptproc;
CHOOSE CASE SQLCA.sqlcode
CASE 0
// Execute successful. There is at least one
// result set. Loop to get the query result set
// from the table SELECT.
DO
FETCH deptproc INTO :fname, :lname, :dSalary;
CHOOSE CASE SQLCA.sqlcode
CASE 0
fetchcount++
CASE 100
MessageBox ("End of Result Set", &
string (fetchcount) " rows fetched")
CASE -1
MessageBox ("Fetch Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
LOOP WHILE SQLCA.sqlcode = 0
// Issue an extra FETCH to get the Return Value
// and Output Parameters.
FETCH deptproc INTO :rc, :dTotSal, :dAvgSal;
CHOOSE CASE SQLCA.sqlcode
CASE 0
MessageBox ("Fetch Return Value and Output" &
"Parms SUCCESSFUL", "Return Value is: " &
string (rc) &
"~r~nTotal Salary: " string (dTotSal) &
"~r~nAverage Sal: " string (dAvgSal))
CASE 100
MessageBox ("Return Value and Output Parms" &
"NOT FOUND", "")
CASE ELSE
MessageBox ("Fetch Return Value and Output" &
"Parms FAILED", "SQLDBCode is " &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
CLOSE deptproc;
CASE 100
// Execute successful; no result set.
// Do not try to close.
MessageBox ("Execute Successful", "No result set")
CASE ELSE
MessageBox ("Execute Failed", &
string (SQLCA.sqldbcode) " = " &
SQLCA.sqlerrtext)
END CHOOSE
#3
:lDeptno参数为char型怎么办?
#4
string 就可以!
#5
声明并执行Oracle存储过程及函数
This document contains an example that creates a stored procedure dynamically with two input arguments and two output arguments.
Overview
This document provides examples of Oracle functions and stored procedures along with the script used to declare and execute them within PowerBuilder. The Powerscript syntax is valid for PowerBuilder 6, 7 and 8. There is a companion PBL is in the PowerBuilder Samples library in the software downloads. that contains the examples. This PBL is written in PowerBuilder 7.
Stored Procedure/Package Synonyms
Oracle 7 Behavior
The Oracle 7 OCI calls that describe stored procedures resolve PUBLIC and private synonyms to correctly describe the procedure. The behavior is similar to the way SQL*Plus resolves the name if you enter "Execute myproc". It first checks to see if you own a stored procedure called "myproc". Failing that, it checks to see if you own a private synonym called "myproc". Failing that, it checks to see if there is a PUBLIC synonym called "myproc".
Oracle 8 Behavior
Oracle changed the OCI calls between Oracle 7 and Oracle 8. Oracle 8 requires a fully qualified object name in the describe call. This is a problem because Powerscript that compiled and worked with the PowerBuilder native drivers for Oracle 7 may now fail at compilation or execution with the native drivers for Oracle 8.
For Example, if you create a public synonym (syn_pkg) for a package that contains stored procedure my_proc, you could reference the procedure as syn_pkg.my_proc when using the native driver for Oracle 7. However, this will cause a script compilation error with Oracle 8. You must change the reference to "PUBLIC".syn_pkg.myproc to make it work. PowerBuilder 7 and higher contain an enhancement that will resolve this behavior internally, which means that either format will work.
If you put quotes around the stored procedure name, the procedure name must be upper-case.
Stored Procedures using DBLink
Overview
The DBLink feature in Oracle allows access to objects on a different Oracle instance than the one you are connected to. Calls are passed to the linked server and, from the client perspective, it all looks like it is coming from the same server.
Oracle 7 Behavior
The PowerBuilder native drivers for Oracle 7 use the OCI odessp() function to describe stored procedures. This function does not support procedures that use a database links whether they are expressed explicitly or by using synonyms. This implies that you cannot use stored procedures across database links in PowerBuilder. The only exception to this rule is that you can specify and RPC declaration for a procedure across a database link as long as it does not contain any PL/SQL table arguments. This will work because the arguments are described in the RPC declaration and no call to odessp() is needed.
Oracle 8 Behavior
Execution of stored procedures / functions are not supported.
Oracle Function Example
Consider the Oracle function declared as follows:
CREATE OR REPLACE FUNCTION system.func_get_empname (
arg_emp_id IN NUMBER) RETURN VARCHAR2 AS
l_lname VARCHAR2(20);
l_fname VARCHAR2(20);
l_name VARCHAR2(42);
BEGIN
SELECT last_name, first_name
INTO l_lname, l_fname
FROM demo.employee
WHERE employee_id = arg_emp_id;
IF SQLCODE <> 0 THEN
l_name := '*** name error ***';
ELSE
l_name := RTRIM(l_lname)||', '||RTRIM(l_fname);
END IF;
RETURN l_name;
END func_get_empname;
This function takes an employee ID as the single input argument and returns the employee name formatted as last name, comma, first name. If a select error occurs, the function returns an error in the return argument.
There are several ways to access this function from PowerBuilder. The following examples show the syntax for each of the methods.
Function called with Powerscript select
The following script shows how to treat the function like an Oracle system function and call it within a Powerscript SELECT INTO statement:
integer l_emp_id = 7555
string l_name
Select func_get_empname(:l_emp_id)
into :l_name
from dual
using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Select Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
This document contains an example that creates a stored procedure dynamically with two input arguments and two output arguments.
Overview
This document provides examples of Oracle functions and stored procedures along with the script used to declare and execute them within PowerBuilder. The Powerscript syntax is valid for PowerBuilder 6, 7 and 8. There is a companion PBL is in the PowerBuilder Samples library in the software downloads. that contains the examples. This PBL is written in PowerBuilder 7.
Stored Procedure/Package Synonyms
Oracle 7 Behavior
The Oracle 7 OCI calls that describe stored procedures resolve PUBLIC and private synonyms to correctly describe the procedure. The behavior is similar to the way SQL*Plus resolves the name if you enter "Execute myproc". It first checks to see if you own a stored procedure called "myproc". Failing that, it checks to see if you own a private synonym called "myproc". Failing that, it checks to see if there is a PUBLIC synonym called "myproc".
Oracle 8 Behavior
Oracle changed the OCI calls between Oracle 7 and Oracle 8. Oracle 8 requires a fully qualified object name in the describe call. This is a problem because Powerscript that compiled and worked with the PowerBuilder native drivers for Oracle 7 may now fail at compilation or execution with the native drivers for Oracle 8.
For Example, if you create a public synonym (syn_pkg) for a package that contains stored procedure my_proc, you could reference the procedure as syn_pkg.my_proc when using the native driver for Oracle 7. However, this will cause a script compilation error with Oracle 8. You must change the reference to "PUBLIC".syn_pkg.myproc to make it work. PowerBuilder 7 and higher contain an enhancement that will resolve this behavior internally, which means that either format will work.
If you put quotes around the stored procedure name, the procedure name must be upper-case.
Stored Procedures using DBLink
Overview
The DBLink feature in Oracle allows access to objects on a different Oracle instance than the one you are connected to. Calls are passed to the linked server and, from the client perspective, it all looks like it is coming from the same server.
Oracle 7 Behavior
The PowerBuilder native drivers for Oracle 7 use the OCI odessp() function to describe stored procedures. This function does not support procedures that use a database links whether they are expressed explicitly or by using synonyms. This implies that you cannot use stored procedures across database links in PowerBuilder. The only exception to this rule is that you can specify and RPC declaration for a procedure across a database link as long as it does not contain any PL/SQL table arguments. This will work because the arguments are described in the RPC declaration and no call to odessp() is needed.
Oracle 8 Behavior
Execution of stored procedures / functions are not supported.
Oracle Function Example
Consider the Oracle function declared as follows:
CREATE OR REPLACE FUNCTION system.func_get_empname (
arg_emp_id IN NUMBER) RETURN VARCHAR2 AS
l_lname VARCHAR2(20);
l_fname VARCHAR2(20);
l_name VARCHAR2(42);
BEGIN
SELECT last_name, first_name
INTO l_lname, l_fname
FROM demo.employee
WHERE employee_id = arg_emp_id;
IF SQLCODE <> 0 THEN
l_name := '*** name error ***';
ELSE
l_name := RTRIM(l_lname)||', '||RTRIM(l_fname);
END IF;
RETURN l_name;
END func_get_empname;
This function takes an employee ID as the single input argument and returns the employee name formatted as last name, comma, first name. If a select error occurs, the function returns an error in the return argument.
There are several ways to access this function from PowerBuilder. The following examples show the syntax for each of the methods.
Function called with Powerscript select
The following script shows how to treat the function like an Oracle system function and call it within a Powerscript SELECT INTO statement:
integer l_emp_id = 7555
string l_name
Select func_get_empname(:l_emp_id)
into :l_name
from dual
using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Select Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
#6
Function called using Remote Procedure Call (RPC)
If your stored procedure or function can be called as a remote Procedure Call (RPC), you will create less code and get better performance by using RPC's. The performance gain comes from the fact that the argument types are already known from the declaration so a costly describe is avoided. PowerBuilder generates the following Local External Function declaration for our example:
function string FUNC_GET_EMPNAME(double ARG_EMP_ID) RPCFUNC ALIAS FOR "~"SYSTEM~".~"FUNC_GET_EMPNAME~""
The code to call the function as an RPC follows:
integer l_emp_id = 7555
string l_name
l_name = sqlca.func_get_empname(l_emp_id)
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
Function called using Powerscript declare and execute
The code to call the function using the Powerscript DECLARE and EXECUTE follows :
integer l_emp_id = 7555
string l_name
declare sp_1 procedure for FUNC_GET_EMPNAME (:l_emp_id) using sqlca;
execute sp_1;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure execute error", sqlca.sqlerrtext)
return
end if
FETCH sp_1 into :l_name;
if sqlca.sqlcode = 0 then
MessageBox("Employee Name", l_name)
else
MessageBox("SQlCode", string(sqlca.sqlcode))
end if
close sp_1;
return
Example Function called with dynamic SQL Format 2
integer l_emp_id = 7555
string l_name
l_name = space(42)
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "select FUNC_GET_EMPNAME(?) from dual" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1 using :l_emp_id;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
end if
fetch sp_1 into :l_name;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Fetch Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
close sp_1;
return
Oracle SP with no argument or result set
The following stored procedure has no arguments and produces no result set. The success or failure information is returned in the SQLDBCode.
CREATE OR REPLACE PROCEDURE system.sp_test_noargs AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Test from sp_test_noargs');
if SQLCODE <> 0 then
RAISE_APPLICATION_ERROR(-20001, 'SQLCODE from put_line was '||TO_CHAR(SQLCODE));
end if;
END sp_test_noargs;
Powerscript Declare and Execute Example
integer l_emp_id = 7555
declare sp_1 procedure for SP_TEST_NOARGS using sqlca;
execute sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure execute error", string(sqlca.sqlcode) + ": " + string(sqlca.sqldbcode) + ": " + sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", sqlca.sqldbcode)
end if
close sp_1;
return
RPC example
Following is the RPC declaration for the stored procedure:
subroutine SP_TEST_NOARGS() RPCFUNC ALIAS FOR SYSTEM.SP_TEST_NOARGS
Following is the Powerscript to execute the stored procedure:
sqlca.sp_test_noargs()
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("RPC Call", "Successful")
end if
return
Powerscript Dynamic execution example
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "execute sp_test_noargs" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", "OK")
end if
close sp_1;
return
If your stored procedure or function can be called as a remote Procedure Call (RPC), you will create less code and get better performance by using RPC's. The performance gain comes from the fact that the argument types are already known from the declaration so a costly describe is avoided. PowerBuilder generates the following Local External Function declaration for our example:
function string FUNC_GET_EMPNAME(double ARG_EMP_ID) RPCFUNC ALIAS FOR "~"SYSTEM~".~"FUNC_GET_EMPNAME~""
The code to call the function as an RPC follows:
integer l_emp_id = 7555
string l_name
l_name = sqlca.func_get_empname(l_emp_id)
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
return
Function called using Powerscript declare and execute
The code to call the function using the Powerscript DECLARE and EXECUTE follows :
integer l_emp_id = 7555
string l_name
declare sp_1 procedure for FUNC_GET_EMPNAME (:l_emp_id) using sqlca;
execute sp_1;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure execute error", sqlca.sqlerrtext)
return
end if
FETCH sp_1 into :l_name;
if sqlca.sqlcode = 0 then
MessageBox("Employee Name", l_name)
else
MessageBox("SQlCode", string(sqlca.sqlcode))
end if
close sp_1;
return
Example Function called with dynamic SQL Format 2
integer l_emp_id = 7555
string l_name
l_name = space(42)
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "select FUNC_GET_EMPNAME(?) from dual" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1 using :l_emp_id;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
end if
fetch sp_1 into :l_name;
if sqlca.sqlcode <> 0 then
MessageBox("Procedure Fetch Error", sqlca.sqlerrtext)
else
MessageBox("Employee Name", l_name)
end if
close sp_1;
return
Oracle SP with no argument or result set
The following stored procedure has no arguments and produces no result set. The success or failure information is returned in the SQLDBCode.
CREATE OR REPLACE PROCEDURE system.sp_test_noargs AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Test from sp_test_noargs');
if SQLCODE <> 0 then
RAISE_APPLICATION_ERROR(-20001, 'SQLCODE from put_line was '||TO_CHAR(SQLCODE));
end if;
END sp_test_noargs;
Powerscript Declare and Execute Example
integer l_emp_id = 7555
declare sp_1 procedure for SP_TEST_NOARGS using sqlca;
execute sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure execute error", string(sqlca.sqlcode) + ": " + string(sqlca.sqldbcode) + ": " + sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", sqlca.sqldbcode)
end if
close sp_1;
return
RPC example
Following is the RPC declaration for the stored procedure:
subroutine SP_TEST_NOARGS() RPCFUNC ALIAS FOR SYSTEM.SP_TEST_NOARGS
Following is the Powerscript to execute the stored procedure:
sqlca.sp_test_noargs()
if sqlca.sqlcode <> 0 then
MessageBox("RPC Error", sqlca.sqlerrtext)
else
MessageBox("RPC Call", "Successful")
end if
return
Powerscript Dynamic execution example
declare sp_1 dynamic procedure for sqlsa;
prepare SQLSA from "execute sp_test_noargs" using sqlca;
if sqlca.sqlcode <> 0 then
MessageBox("Prepare Error", sqlca.sqlerrtext)
return
end if
execute dynamic sp_1;
if sqlca.sqlcode < 0 then
MessageBox("Procedure Execute Error", sqlca.sqlerrtext)
return
else
MessageBox("Procedure Result", "OK")
end if
close sp_1;
return
#7
Fetch