Создание хранимой процедуры Oracle из кода C# не удается для разработчика PL/SQL

Я попытался создать процедуру SQL на сервере Oracle. Вот мой код,

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 в varchar2, No в varchar2,

Я думаю, что это вызвано форматированием строки в коде С#. Потому что, если я выполняю тот же код SQL на сервере Oracle, процедура создается без проблем.

Какое хорошее решение этой проблемы?


person Community    schedule 18.08.2011    source источник
comment
Не создавайте таблицы или хранимые процедуры в схеме SYSTEM. Это очень плохая идея. Это может не быть причиной вашей непосредственной проблемы, но вызвать множество других проблем.   -  person Codo    schedule 19.08.2011


Ответы (4)


Возможно, это символы новой строки, встроенные в вашу строку 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> 
person DCookie    schedule 18.08.2011

Возможно, это из-за названия. У вас есть параметр и столбец с именем Type, которые согласно этому страница — это зарезервированное слово.

Я также очень не хотел бы иметь те же имена для параметров, что и для столбцов. Я бы добавил к параметрам префикс in или аналогичный, поэтому у меня было бы что-то вроде inId вместо Id.

В общем, я бы предложил, чтобы один из способов проверить это - изменить код, чтобы создать очень простую процедуру без параметров, которая ничего не делает, и посмотреть, работает ли это, если да, то добавить один параметр и т. д., пока это ломает.

person Hans Olsson    schedule 18.08.2011
comment
Хотя это и не является хорошей практикой, использование зарезервированных слов здесь не является проблемой. Смотрите мой ответ. - person DCookie; 19.08.2011

Я думаю, что вы ошибаетесь в этом выводе:

Потому что, если я выполняю тот же код SQL на сервере Oracle, процедура создается без проблем.

Процедура создавалась без ошибок, а потом компилировалась с ошибками - но молча.

Если вы используете sqlplus или sqlplusw просто выполните SHOW ERRORS сразу после создания процедуры.

Если вы используете расширенные средства разработки, такие как PL/SQL Developer, TOAD, SQL Navigator или SQL Developer просто откройте созданный в специальном окне редактора и попробуйте скомпилировать его здесь. Вы должны увидеть те же ошибки компиляции.

В любом случае вы должны исправить некоторые ошибки в коде процедуры: использование зарезервированных слов (type) в качестве имени параметра и т.д.

person ThinkJet    schedule 18.08.2011

Спасибо за ответ, проблема была в форматировании строки в 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 и перемещаю таблицу из системы схемы.

person Community    schedule 19.08.2011