我们在C#程序中使用Oracle存储过程,该程序运行正常,直到我们添加了'v_nameurn'变量。
这是Oracle程序:
create or replace procedure stats_By_Date (
v_SDate IN varchar2,
v_EDate IN varchar2,
v_user IN number,
v_nameurn IN number,
p_cursor OUT SYS_REFCURSOR
) as
BEGIN
OPEN p_cursor FOR
select T1.Staff_No,
T3.Title,
T2.Verno,
To_char(T1.Response_dt, 'DD/MM/YYYY'),
T5.Response,
T6.Forenames||' '||T6.Surname
from TOU.Users_version_link T1,
TOU.Version T2,
TOU.name T3,
TOU.Admin_Access T4,
Tou.CV_Response T5,
corp.wforce_employee@remote_DWLive T6
where T1.Version_urn=T2.Urn
and T1.Name_urn= T3.urn
and T3.urn = T4.name_urn
and T1.Response_urn=T5.urn
and T1.staff_no=T6.Staff_Number
and Trunc(T1.Response_dt) >= To_date(v_Sdate, 'DD/MM/YYYY')
and Trunc(T1.Response_dt) <= To_date(v_EDate, 'DD/MM/YYYY')
and T4.Staff_No = v_user
and T3.urn = v_nameurn;
End;
这是C#代码:
this.ConnectToDb();
var cmd = new OracleCommand
{
Connection = cn,
CommandText = "TOU.Stats_By_Date",
CommandType = CommandType.StoredProcedure
};
var id = HttpContext.Current.User.Identity.Name.Split('\\')[1].ToString();
cmd.Parameters.Add("v_SDate", OracleDbType.Varchar2).Value =
startdate.ToString("dd-MM-yyyy");
cmd.Parameters.Add("v_EDate", OracleDbType.Varchar2).Value =
enddate.ToString("dd-MM-yyyy");
cmd.Parameters.Add("v_user", OracleDbType.Decimal).Value = int.Parse(id);
cmd.Parameters.Add("v_nameurn", OracleDbType.Decimal).Value = 3;
var rc = cmd.Parameters.Add("p_cursor", OracleDbType.RefCursor);
rc.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
this.DisconnectFromDb();
有什么可能出错的建议吗?两段代码中共有5个变量(4个,1个),这很好,所有数据类型似乎都匹配。我还尝试了实际v_nameurn
变量的不同变体,所以我尝试了3,“3”,并事先将其定义为Int变量。
答案 0 :(得分:2)
Decimal is Oracle NUMBER type
..所以更改v_user
和'v_nameurn'的数据类型
cmd.Parameters.Add("v_user", OracleDbType.Decimal).Value = int.Parse(id);
cmd.Parameters.Add("v_nameurn", OracleDbType.Decimal).Value = 3;
答案 1 :(得分:2)
cmd.Parameters.Add("v_user", OracleDbType.Decimal).Value = decimal.Parse(id);
cmd.Parameters.Add("v_nameurn", OracleDbType.Decimal).Value = 3m;
处理小数时必须使用小数。对于Oracle,小数不能很好地转换为整数,反之亦然。
答案 2 :(得分:1)
这是oracle证明不是开发人员友好的RDBMS的错误之一。为什么他们不能告诉你这两个问题中的哪一个是我不知道的问题。我有一个啰嗦list of things to check归结为以下内容:
然而,从这个看起来,我想我要在我的列表中添加一个:确保你正在调用你认为你正在呼叫的程序。我在程序中看到了“TOU”限定符。我必须假设这是一个模式而不是基于sql脚本的包。你在改变这个模式中的proc吗?如果删除.net代码中的新参数,它是否有效或者是否会出现相同的错误?您应该得到相同的错误,但如果不这样做,您可能会将新的proc加载到错误的模式。
你可以做的最后一件事就是从一个proc的shell开始,一次添加一个proc,直到你能弄清楚发生了什么。
我会说你的int.Parse(id)有点奇怪 - 你认证的用户ID只是整数?但无论如何我都希望有一个.net错误而不是oracle错误。
答案 3 :(得分:0)
在不同的情况下,我遇到了相同的错误。
使用 OleDB 和早期版本的Oracle,您无需在调用存储过程时设置return参数:
PROCEDURE getThingByID
(thingID NUMBER,
results IN OUT tSelectCursor) IS
selectCursor tSelectCursor;
BEGIN
OPEN selectCursor FOR
SELECT Name, Description, IsDeleted
FROM thing WHERE thingID = getThingByID.thingID;
results := selectCursor;
END;
C#/伪指令:
cn = New OleDbConnection("Provider=msdaora.1;Data Source=myTNSEntry;User ID=fakeuser;Password=abc123");
cn.Open();
oleDBCmd = cn.CreateCommand();
oleDBCmd.CommandType = CommandType.StoredProcedure;
oleDBCmd.CommandText = "ThingPackage.GetThingByID";
oleDBCmd.Parameters.Add(new OleDbParameter("thingID", "1"));
我们在没有 tSelectCursor 输入输出参数的情况下执行它:
dataReader = oleDBCmd.ExecuteReader();
按照:C# and Oracle 10g database to call stored procedure
但是,重要的是要注意,如果在Oracle 12c数据库上执行此操作,则在10g数据库上使用Oracle 9.2驱动程序时会发生错误:
“ ORA-06550:PLS-00306:调用'GETTHINGBYID'时参数或类型错误”
我发现如果您确实指定了期望的输出参数:
oleDBCmd.Parameters.Add(parm);
您没有获得PLS-00306:对{proc name}的调用中错误的数目或参数类型,但是添加后得到:
size属性的大小无效为0
这使我们几乎没有选择(我不知道如何克服这个问题)来求助于Oracle Managed Data ODP.Net驱动程序。
使用 ODP.Net ,您必须在调用存储过程时设置返回参数,与OleDB不同,Oracle驱动程序提供了REFCURSOR输出参数:
PROCEDURE getThingByID2
(thingID NUMBER,
results OUT SYS_REFCURSOR) IS
BEGIN
OPEN refCursor FOR
SELECT Name, Description, IsDeleted
FROM thing WHERE thingID = getThingByID2.thingID;
END;
现在我们可以轻松地称呼它:
ocn = New OracleConnection("Data Source=myTNSEntry;User ID=fakeuser;Password=abc123");
ocn.Open();
ocmd = ocn.CreateCommand();
ocmd.CommandType = CommandType.StoredProcedure();
ocmd.CommandText = "ThingPackage.GetThingByID2";
ocmd.Parameters.Add(New OracleParameter("thingID", "1"));
ocmd.Parameters.Add(New OracleParameter("results", OracleDbType.RefCursor, ParameterDirection.InputOutput));
dataReader = ocmd.ExecuteReader();
使用SSL时,您可能会遇到.Net Oracle SSL Wallet问题“网络传输:解析钱包位置时SSL失败” : Oracle.ManagedDataAccess to AWS RDS DB - TCPS: Invalid SSL Wallet (Magic)