Почему один и тот же скрипт PL/SQL работает в SQL Developer, но не работает при вызове из кода на C#?

117
10 сентября 2021, 13:30

Доброго времени всем читающим!

Помогите, пожалуйста, разобраться с вызовом процедур из кода на C#.

В общем есть база данных Oracle, из которой требуется вызвать несколько процедур, вот код этих процедур на PL/SQL:

1)

procedure changeDepId(owid in number)
  is
  -- DepositoryId t25.t25dsid%TYPE;
  begin
  --  DepositoryId := DIVISION.GetDepositoryId(owid);
  --  if DepositoryId is null then
  --    DepositoryId := owid;
  --  end if;
    UPDATE t25
    SET t25owid = owid, t25dsid = owid
    WHERE T25EMID = InitSubj.getuserpar('EMID');
--    EVENT.SendTextMessage( InitSubj.getuserpar('EMID'), 110, 5);
  end;

2)

PROCEDURE PreInit(
   sOperatorLogon IN    varchar2,
   sBaseCreator   IN    varchar2,
   sCompName      IN    varchar2,
   sVersion       IN    varchar2,
   nOperatorID    OUT   number,
   nWorkstationID OUT   number,
   nPLSQLerror    OUT   number,
   sPLSQLerror    OUT   varchar2,
   nCountOWID     OUT   number,
   sDBName        OUT   NOCOPY   varchar2,
   sSchemaName    OUT   NOCOPY   varchar2
)
IS
   logon varchar2(200);
   bs_creator varchar2(200);
   emid integer;
   ofid integer;
BEGIN
   g_bIsUserSession := TRUE;
   logon := Upper(sOperatorLogon);
   bs_creator := Upper(sBaseCreator);
   emid := -2;
   ofid := -2;
   nCountOWID := 0;
    INITSUBJ.preinit(logon, sCompName, sVersion, emid, ofid);
    nPLSQLerror := INITSUBJ.getError(sPLSQLerror);
    nOperatorID := emid;
    nWorkstationID := ofid;
    IF logon != bs_creator THEN
        SELECT COUNT(E.T26OWID) INTO nCountOWID FROM T26 E, T26 O WHERE E.T26MBST = 110 AND E.T26EMID = emid AND O.T26MBST=100 AND O.T26EMID=ofid AND E.T26OWID=O.T26OWID;
    END IF;
   select
      SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA'),
      Upper(SYS_CONTEXT('USERENV', 'DB_NAME'))
   into
      sSchemaName,
      sDBName
   from dual;
END;

В первом примере процедура апдейтит таблицу t25, во втором инициализируется сессия. Пробовал написать скрипт на PL/SQL с вызовом двух процедур, вот, что получилось:

DECLARE
  ownerid NUMBER;
  --исходящие параметры процедуры preinit
  opID       NUMBER;
  workstID   NUMBER;
  plsqlerr   NUMBER;
  splsqler   VARCHAR2(1000);
  countowid  NUMBER;
  dbname     VARCHAR2(1000);
  schemaname VARCHAR2(1000);
  --Ошибки
  initPLSQLerror  NUMBER;
  iinitPLSQLerror VARCHAR2(1000);
BEGIN
  -- получение owid филиала
  SELECT t28owid
  INTO ownerid
  FROM t28
  WHERE t28ownm = '{filial}';
  -- вызов функции смены подразделения
  INITSUBJ.changedepid(ownerid);
  --инициализация сессии
  SESSION_UTIL.preinit('{login}', NULL, NULL, NULL, opid, workstid, plsqlerr, splsqler, countowid, dbname, schemaname);
  COMMIT;
END;

Так вот этот скрипт безупречно работает в SQL Developer, но в при вызове из кода на C# скрипт не отработал. Просто записываю скрипт в OracleCommand OracleCommand cmd = new OracleCommand(script, connection);, по-умолчанию cmd.CommadType = CommandType.Text, после выполняю скрипт через метод cmd.ExecuteNonQuery(); и этот метод после выполнения возвращает значение -1, т.е. в таблице t25 не была изменена ни одна запись.

Пробовал вызывать процедуры напрямую:

OracleConnection connection = new OracleConnection();
connection.ConnectionString = connString;
connection.Open();
OracleCommand cmd = new OracleCommand($"SELECT t28owid FROM t28 WHERE t28ownm = '{filial}'", connection);
var fl = cmd.ExecuteScalar();
OracleTransaction transaction = conn.BeginTransaction();
OracleCommand cmd2 = new OracleCommand("INITSUBJ.changeDepId", connection);
cmd2.Transaction = transaction;
cmd2.CommandText = "INITSUBJ.changeDepId";
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.Parameters.Add("@owid", OracleDbType.Decimal).Value = fl;
var resultchangedep = cmd2.ExecuteNonQuery();
OracleCommand cmd3 = new OracleCommand("SESSION_UTIL.preinit", conn);
cmd3.Transaction = transaction;
cmd3.CommandType = CommandType.StoredProcedure;
cmd3.Parameters.Add("@sOperatorLogon", OracleDbType.Varchar2).Value = login;
cmd3.Parameters.Add("@sBaseCreator", OracleDbType.Varchar2);
cmd3.Parameters.Add("@sCompName", OracleDbType.Varchar2);
cmd3.Parameters.Add("@sVersion", OracleDbType.Varchar2);
cmd3.Parameters.Add("@nOperatorID", OracleDbType.Decimal, 1000, null, ParameterDirection.Output);
cmd3.Parameters.Add("@nWorkstationID", OracleDbType.Decimal, 1000, null, ParameterDirection.Output);
cmd3.Parameters.Add("@nPLSQLerror", OracleDbType.Decimal, 1000, null, ParameterDirection.Output);
cmd3.Parameters.Add("@sPLSQLerror", OracleDbType.Varchar2, 1000, null, ParameterDirection.Output);
 cmd3.Parameters.Add("@nCountOWID", OracleDbType.Decimal, 1000, null, ParameterDirection.Output);
cmd3.Parameters.Add("@sDBName", OracleDbType.Varchar2, 1000, null, ParameterDirection.Output);
cmd3.Parameters.Add("@sSchemaName", OracleDbType.Varchar2, 1000, null, ParameterDirection.Output);
var resultpreinit = cmd3.ExecuteNonQuery();
transaction.Commit();
conn.Close();
conn.Dispose();

Но и в этом случае UPDATE таблицы t25 почему-то не произошел, хотя я, как видно, ещё попытался создать транзакцию и после работы с базой закрыть транзакцию, метод ExecuteNonQuery() в этот раз так же вернул -1. Ещё пробовал использовать метод ExecuteReader() (не знаю зачем, наверное, от отчаяния) и в свойстве RecordsAffected объекта OracleDataReader всё так же значение -1.

Код пишу в Visual Studio 2015, операционная система Windows Server 2008 R2, версия базы Оракла - 11.2g.

Помогите, пожалуйста, разобраться почему один и тот же скрипт работает в SQL Developer, но не работает при вызове из кода на C#.

Кстати, что в SQL Developer, что в коде подключаюсь к базе под одним и тем же пользователем.

READ ALSO
Кастомный ProgresBar WPF

Кастомный ProgresBar WPF

Помогите сделать кастомный ProgressBar прочитал этот и этот пост дело в том, что мне нужен ProgressBar не совсем правильной(круглой) формы

106
TypeError: Cannot read property 'length' of undefined

TypeError: Cannot read property 'length' of undefined

помогите разобраться в следующем плс: на данный момент настроил пагинацию и сортировку, но для некоторыx условий, которые я задаю в ангуляре...

84
C# шаблон проверка типа T

C# шаблон проверка типа T

Есть такой Метод

108