【问题标题】:Oracle stored procedure creation from C# code fails for PL/SQL developerPL/SQL 开发人员从 C# 代码创建 Oracle 存储过程失败
【发布时间】:2011-08-18 18:35:47
【问题描述】:

我尝试在 Oracle 服务器上创建 SQL 过程。这是我的代码,

private const string InsertCallProc =
        @"CREATE OR REPLACE PROCEDURE INSERTCALL (Id in varchar2,No in varchar2,
           Surname in varchar2, Name in varchar2, CallType in varchar2,
           CallDate in date, CallNo in varchar2, VoiceNetwork in varchar2,
           Type in varchar2,TalkTime in number,PriceWithDiscount in number,
           PriceWithoutDiscount in number, LmTime in date)
        AS
            BEGIN
                INSERT INTO TMOBILE_R_CALLS (ID,NO,SURNAME,NAME,CALL_TYPE,CALL_DATE,CALL_NO, 
                    VOICE_NETWORK, TYPE,TALK_TIME, PRICE_WITH_DISCOUNT, PRICE_WITHOUT_DISCOUNT,LM_TIME)
                VALUES(Id, No, Surname, Name, CallType,CallDate, CallNo, VoiceNetwork,Type, TalkTime, 
                    PriceWithDiscount,PriceWithoutDiscount, LmTime);
    END;";

执行此sql cmd的方法,输入参数为InsertCallProc字段。

    private void ExecuteNonQueryCmd(string cmdText)
    {
        using (var conn = new OracleConnection(GenerateConnectionString()))
        {
            conn.Open();

            var cmd = new OracleCommand
            {
                Connection = conn,
                CommandText = cmdText
            };

            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

如果我调用了这个方法,就会创建过程。但是,如果我检查 PL/SQL 开发人员中的过程,我会看到:

PROCEDURE SYSTEM.INSERTCALL 的编译错误

错误:PLS-00103:在期望其中一个时遇到符号“” 以下:

当前行:1 文本:CREATE OR REPLACE PROCEDURE INSERTCALL (Id in varchar2,varchar2中没有,

我认为这是由于在 C# 代码中格式化字符串造成的。因为如果我在 Oracle 服务器上执行相同的 SQL 代码,创建过程就没有问题。

这个问题有什么好的解决方案?

【问题讨论】:

  • 不要在模式 SYSTEM 中创建表或存储过程。这是一个非常糟糕的主意。这可能不是您当前问题的原因,但会导致许多其他问题。

标签: c# sql oracle procedure


【解决方案1】:

这可能是由于命名。你有一个参数和一个列都称为Type,根据这个page是一个保留字。

我也非常不愿意将参数的名称与列的名称相同。我会在参数前加上in 或类似的前缀,所以我会有inId 之类的东西,而不仅仅是Id

总而言之,我建议测试它的一种方法是更改​​代码以创建一个没有参数的非常基本的过程,它什么都不做,看看它是否有效,如果有效,然后添加一个参数等,直到它中断。

【讨论】:

  • 虽然不是一个好习惯,但保留字的使用在这里不是问题。看我的回答。
【解决方案2】:

可能是嵌入在 C# 字符串中的换行符。错误

在预期以下之一时遇到符号“”

向我表明,遇到了一个不可打印的特殊字符。也说明问题出在第一行。

此外,在 SYSTEM 或 SYS 架构中创建对象通常是个坏主意。

至于指责保留字使用的答案:虽然这不是一个很好的做法,但它可能不是这里的罪魁祸首:

SQL> CREATE OR REPLACE PROCEDURE p(TYPE IN VARCHAR2) IS
  2  BEGIN
  3    dbms_output.put_line(TYPE);
  4  END;
  5  /

Procedure created
SQL> DECLARE
  2  BEGIN
  3    p('This is a test');
  4  END;
  5  /

This is a test

PL/SQL procedure successfully completed

SQL> 

【讨论】:

    【解决方案3】:

    我认为你对这个结论有误:

    因为如果我在 Oracle 服务器程序上执行相同的 SQL 代码是 创建没有问题。

    过程创建时没有错误,然后编译时出现错误 - 但静默。

    如果您使用sqlplussqlplusw,只需在创建过程后立即执行SHOW ERRORS 命令即可。

    如果您使用高级开发工具,如PL/SQL DeveloperTOADSQL NavigatorSQL Developer,只需在专用编辑器窗口中打开创建的函数并尝试在此处编译。您必须看到相同的编译错误。

    在任何情况下你都必须修复过程代码中的一些错误:使用保留字(type)作为参数名等等。

    【讨论】:

      【解决方案4】:

      谢谢你的回答,问题是在 C# 中格式化字符串。我解决了这个问题:

          public static string CreateInsertCallProc =
                  "CREATE OR REPLACE PROCEDURE INSERTCALL (inId in varchar2,inSimCard in varchar2,\n" +
                      "inSurname in varchar2, inName in varchar2, inCallType in varchar2,\n" +
                      "inCallDate in date, inCallNo in varchar2, inVoiceNetwork in varchar2,\n" +
                      "inTimeType in varchar2,inTalkTime in number,inPriceWithDiscount in number,\n" +
                      "inPriceWithoutDiscount in number, inLmTime in date)\n" +
                  "AS\n" +
                      "BEGIN\n" +
                          "INSERT INTO TMOBILE_R_CALLS (ID,SIM_CARD,SURNAME,NAME,CALL_TYPE,CALL_DATE,CALL_NO,\n" +
                              "VOICE_NETWORK, TIME_TYPE,TALK_TIME, PRICE_WITH_DISCOUNT, PRICE_WITHOUT_DISCOUNT,LM_TIME)\n" +
                          "VALUES(inId, inSimCard, inSurname, inName, inCallType, inCallDate, inCallNo, inVoiceNetwork,\n" +
                              " inTimeType, inTalkTime,inPriceWithDiscount,inPriceWithoutDiscount, inLmTime);\n" +
              "END;";
      

      我还将列名从 Type 更改为 Time_Type,并从模式系统中移动表

      【讨论】:

        猜你喜欢
        • 2017-12-21
        • 2012-09-29
        • 2020-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-26
        相关资源
        最近更新 更多