ORA-00922: 缺失或无效选项。当尝试从C#执行PL/SQL时。

3
我几乎可以确定这是用户错误。
我刚开始连接C#到Oracle数据库,已经按照Oracle在线文档的代码进行建模。我的PL/SQL在Oracle SQL Developer中可以正常运行。但在test.aspx页面中,我遇到了如下错误:
ORA-00922:缺少或无效的选项
test.aspx.cs页面的后台代码为:
string currentTerm = getCurrentTerm();
    string passwd = "<get password input>";
    string salt = "<get salted input>";

    conn.ConnectionString = ConfigurationManager.ConnectionStrings["CONNECTIONSTRINGNAME"].ConnectionString;

        conn.Open();

        // pl/sql block
        string pl_sql = "  set serveroutput on " +
                                    "DECLARE"+
                                    "   output                 tablename.function%TYPE;" +
                                    "BEGIN"+
                                    "   tablename.myfunction(:1,:2,:3);" +
                                    "   dbms_output.put_line('output= '||output"+
                                    "END;";

        //Oracle Parameters necessary for the myfunction function
        OracleParameter p_1 = new OracleParameter(passwd, OracleDbType.Varchar2, 50, ParameterDirection.Input);
        OracleParameter p_2 = new OracleParameter(salt, OracleDbType.Varchar2, 50, ParameterDirection.Input);
        OracleParameter p_3 = new OracleParameter("3", OracleDbType.Varchar2, 50, ParameterDirection.Output);

        // create the command object
        OracleCommand cmd = conn.CreateCommand();
        cmd.CommandText = pl_sql;

        // add the parameters
        cmd.Parameters.Add(p_1);
        cmd.Parameters.Add(p_2);
        cmd.Parameters.Add(p_3);

        // execute the pl/sql block
        cmd.ExecuteNonQuery();

        // get a data reader from the ref cursor 
        //    note: this is on p_3, the output value
        OracleDataReader dr = ((OracleRefCursor)p_3.Value).GetDataReader();

        while (dr.Read())
        {

            Response.Write("Salt licked hash: "+ dr[0].ToString());
            //Output the line retrieved from dbms_output.put line
            Response.Write("<br />");
            Response.Write("DBMS_OUTPUT STATUS: "+ p_3.Value.ToString());

        }
2个回答

9

1) SET SERVEROUTPUT ON 是SQLPlus函数,它不是SQL或PL/SQL语言的一部分(尽管许多GUI(如SQL Developer和Toad)至少支持SQLPlus类似这样的函数)。

2) 您几乎肯定不想使用 DBMS_OUTPUT 处理与应用程序相关的任何内容 - 这不是从 PL/SQL 块获取数据的正确方法。从技术上讲,您可以在 PL/SQL 块中调用 DBMS_OUTPUT.ENABLE(<<缓冲区大小>>),使用 DBMS_OUTPUT.PUT_LINE 向缓冲区写入数据,然后让您的应用程序调用 DBMS_OUTPUT.GET_LINE 以读取程序完成后从缓冲区中读取数据。那就是 SQL*Plus 和 SQL Developer 在幕后执行的操作。但这不是构建应用程序的合适方式。

3) 我不确定 tablename.myfunction 返回的是什么类型。如果它返回一个简单的标量或 REF CURSOR,那么就容易得多 - 您只需像 Harrison 在此 SO 线程中演示的那样在不带 PL/SQL 匿名块的情况下调用该函数,以返回 REF CURSOR。如果它返回一个 PL/SQL 记录类型,则 Mark Williams 在 OTN 论坛上有一个示例展示了在 C# 中返回 PL/SQL 记录的匿名 PL/SQL 块。


tablename.myfunction返回Varchar2。我进行了您建议的更改,但出现了新错误...我认为这很好。ORA-06502:PL / SQL:数值或值错误:字符字符串缓冲区太小ORA-06512:在“REDACTED_TABLE”的第77行ORA-06512:在“REDACTED_TABLE”的第130行ORA-06512:在第1行 - Geekender
@user834436 - 假设REDACTED_TABLE是一个函数名,那么在第130行和第77行有什么内容? - Justin Cave
哦,我猜这是一个函数而不是表。快速问题,现在可能只是权限问题吗?如果是这样,为什么它可以在SQL Developer中工作,而不能使用C#代码? - Geekender
@user834346 - 第三个参数是一个OUT参数。在您的原始代码中,您传递了一个50个字符的缓冲区。您确定这个缓冲区足够大吗? - Justin Cave
很有趣,你提到了这个。我正在查看文档,发现他们正在使用2000,所以我将我的代码更改为:code//Oracle Parameters necessary for the myfunction function OracleParameter p_1 = new OracleParameter(passwd, OracleDbType.Varchar2, 2000, ParameterDirection.Input); OracleParameter p_2 = new OracleParameter(salt, OracleDbType.Varchar2, 2000, ParameterDirection.Input); OracleParameter p_3 = new OracleParameter(output, OracleDbType.Varchar2, 2000, ParameterDirection.Output); - Geekender

2

我没有看到你关闭这个语句 dbms_output.put_line('output= '||output"+


好的观点。不过那并没有解决问题。还是同样的错误。在Oracle SQL Developer中可以成功完成。 - Geekender

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接