在oracle块中为绑定变量(c#输出参数)指定一个文字

本文关键字:文字 一个 参数 oracle 绑定 变量 输出 | 更新日期: 2023-09-27 18:02:38

我正在开发一个c#应用程序,并将SQL语句从SQL Server转换为Oracle。我有一个块,其中值被插入到一个主表和几个记录在一个相关的表。我需要确定主表中是否存在重复的记录,并将标记值返回到c#页面,如果存在,则插入记录,获取主表的PK并将其用于插入相关表。到目前为止,我发现在块中从Oracle返回值的最佳方法是使用InputOutput参数。(如果在语句中有一个BEGIN/END块,它将不允许我在没有INTO的情况下进行SELECT。)

在SQL Server中,试图从没有返回记录的SELECT语句加载变量只会导致变量保持不变。在Oracle中,我发现我需要设置NO_DATA_FOUND异常来处理这个问题。我希望异常设置返回标志;但是我收到"ORA-06502: PL/SQL:数字或值错误"。

BEGIN 
    SELECT ID INTO :REPORTID FROM Report WHERE ExtractDt=:EXTRACTDT 
        AND REGION=:RGN; 
    EXCEPTION WHEN NO_DATA_FOUND THEN 
        SELECT -1 INTO :REPORTID FROM DUAL; 
END;

这是我最接近的。错误发生在SELECT -1…行

reporttid作为NUMBER类型和方向的参数传入;EXTRACTDT是一个具有有效值的日期,RGN是一个varchar(2)字符串;both输入参数。

编辑:从c#向Oracle发送数据块的示例:

OracleCommand psCmd = new OracleCommand();
psCmd.Connection = Conn; //Previously defined, valid & opened
psCmd.CommandType = CommandType.Text;
psCmd.CommandText = "{SQL STRING CONTAINING BLOCK, AS ABOVE}";
psCmd.Parameters.Add(new OracleParameter("REPORTID", OracleType.Number, 10) { Direction = ParameterDirection.InputOutput, Value = DBNull.Value });
psCmd.Parameters.Add(new OracleParameter("EXTRACTDT", OracleType.DateTime) { Value = dtExtract }); //C# DateTime with valid date
psCmd.Parameters.Add(new OracleParameter("RGN", OracleType.VarChar, 2) { Value = sRegion }); //C# String, 2 characters
psCmd.ExecuteNonQuery();
Int32 iID = (Int32)psCmd.Parameters["REPORTID"].Value;
//Cleanup, etc.

在oracle块中为绑定变量(c#输出参数)指定一个文字

问题可能是你正在使用OracleDbType而不是DbType。我通常使用OracleDbType,但在这种情况下,你选择一个数字到一些变量(选择-1到…),它返回一个十进制类型,而不是一个Int。下面这个简单的例子适合我:

string connStr = "User Id=myuser;Password=mypass;Data Source=myinstance;";
                using (OracleConnection con = new OracleConnection(connStr))
                {
                    string s = @"BEGIN
                    select 1 into :TESTID from dual where 1=0;
                    EXCEPTION
                    when no_data_found then
                    select -1 into :TESTID from dual; 
                    END;";
                    using (OracleCommand cmd = new OracleCommand(s, con))
                    {
                        con.Open();
                        Console.WriteLine("Running statement");
                        OracleParameter prm = new OracleParameter();
                        cmd.Parameters.Clear();
                        cmd.BindByName = true;
                        //prm = new OracleParameter("TESTID", OracleDbType.Int32, ParameterDirection.InputOutput); prm.Value = 0; cmd.Parameters.Add(prm);
                        prm = new OracleParameter();
                        prm.ParameterName = "TESTID";
                        prm.DbType = DbType.Int32; // don't use OracleDbType, will return decimal in some cases, not int
                        prm.Direction = ParameterDirection.InputOutput;
                        prm.Value = 0;
                        cmd.Parameters.Add(prm);
                        cmd.ExecuteNonQuery();
                        // may have cast/conversion issues here if using OracleDbType
                        int id = Convert.ToInt32(cmd.Parameters["TESTID"].Value);
                        Console.WriteLine("ID is: " + id);
                        con.Close();
                    }
                }