2016-11-09 4 views
0

Моя хранимая процедура имеет 4 параметра: 3 строки в качестве входных данных и одну строку в качестве вывода.Вызов внешней хранимой процедуры AS400 из C# с выходным параметром

using (OdbcConnection cn = ODBC.Instance.AmulibConnection) 
{ 
    cn.Open(); 

    using (OdbcCommand cm = cn.CreateCommand()) 
    { 
     cm.CommandText = "CALL RET_IMPL_STS('?','?','?','?')"; 
     cm.CommandType = CommandType.StoredProcedure; 

     cm.Parameters.Add("@P1", OdbcType.Char).Value = "1"; 
     cm.Parameters["@P1"].Size = 1; 
     cm.Parameters["@P1"].Direction = ParameterDirection.Input; 

     cm.Parameters.Add("@P2", OdbcType.Char).Value = "ABC"; 
     cm.Parameters["@P2"].Size = 15; 
     cm.Parameters["@P2"].Direction = ParameterDirection.Input; 

     cm.Parameters.Add("@P3", OdbcType.Char).Value = "DEF"; 
     cm.Parameters["@P3"].Size = 6; 
     cm.Parameters["@P3"].Direction = ParameterDirection.Input; 

     cm.Parameters.Add("@P4", OdbcType.Char); 
     cm.Parameters["@P4"].Size = 5; 
     cm.Parameters["@P4"].Direction = ParameterDirection.Output; 

     cm.Prepare(); 
     cm.ExecuteNonQuery(); 

     string result = cm.Parameters["@P4"].Value.ToString(); 

     return result; 
    } 
} 

Я получаю следующее сообщение об ошибке:

Additional information: ERROR [HY000] [IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0469 - IN, OUT, or INOUT not valid for parameter 4 in procedure RET_IMPL_STS in *N.

Что такое правильный синтаксис для выходного параметра?

+0

вы пробовали https: // MSDN.microsoft.com/en-us/library/system.data.parameterdirection(v=vs.110).aspx параметр inout или возвращаемого типа – danny117

+0

Есть ли у вас ответ? Если нет, нам, вероятно, нужно будет знать, как хранится процесс proc, чтобы определить, почему SQL0469 возвращается. – user2338816

+0

Да, у меня есть. Это была проблема синтаксиса, см. Ответ ниже – ehh

ответ

1

Ниже приведены 2 возможно варианты:

  1. Нам нужно удалить котировки, даже если t он имеет параметры:

    см.CommandText = "CALL RET_IMPL_STS (?,?,?,?)";

    Тогда нам нужно указать каждый 4 параметра

  2. следующий синтаксис также будет работать нормально:

    cm.CommandText = string.Format ("CALL RET_IMPL_STS ('{0}',«{1 } ',' {2} ',?) ", STIDAD, ITNOAD, ITRVAD);

    В этом случае нам нужно указать только выходной параметр. Обратите внимание, что в этом формате для строковых параметров требуются кавычки.

-1

На первый взгляд кажется, что у вас отсутствуют некоторые фигурные скобки. Попробуйте использовать следующую команду, чтобы создать новый объект OdbcCommand

OdbcCommand cm = new OdbcCommand("{CALL RET_IMPL_STS('?','?','?','?')}", cn); 

Пожалуйста, прочитайте больше на: https://support.microsoft.com/en-us/kb/310130

+0

По-прежнему получаю ту же ошибку – ehh

0

Чтение @ ссылку Андрея я нашел этот пункт:

When a stored procedure returns a resultset, the output parameter(s) and return value are not available until the resultset has been accessed and closed. For example, if we omitted the line "dr.Close()" in the second sample above, we would be unable to retrieve the values for the output parameter and the return value.

+0

Я также пробовал этот пример, но ошибка произошла раньше в строке выполнения. – ehh

+1

@ehh Я нашел статью в CodeProject. Это класс, который инкапсулирует API DB2. Возможно, вы можете найти там больше информации. http://www.codeproject.com/Articles/5532/DB-Access-Classes – McNets

2

Я рекомендую использовать библиотеку IBM cwbx. Это IBM lib, созданная для взаимодействия между настольными компьютерами и IBM AS400.

Посмотрите здесь: http://timtrott.co.uk/calling-ibm-iseries-rpg-programs-api-calls/ Об этом говорится, как вызвать процедуру с параметрами, расположенными на IBM AS400, и вернуть некоторые значения. Поверьте мне, я уже выполнил эту задачу, и она сработала.

Все это просто включает файл cwbx.dll, создавая экземпляр машины и объекта программы, заполняя их ProgrammParameters (определяя ввод, вывод AND inout-parameter) и вызывающий его.

using System; 
using System.Collections.Generic; 
using System.Text; 
using cwbx; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string result = string.Empty; 

      StringConverter stringConverter = new StringConverterClass(); 

      // Define an AS400 system and connect to it 
      AS400System system = new AS400System(); 
      system.Define("AS400"); 
      system.UserID = "USERNAME"; 
      system.Password = "PASSWORD"; 
      system.IPAddress = "127.0.0.1"; 
      system.Connect(cwbcoServiceEnum.cwbcoServiceRemoteCmd); 

      // Check the connection 
      if (system.IsConnected(cwbcoServiceEnum.cwbcoServiceRemoteCmd) == 1) 
      { 
       // Create a program object and link to a system     
       cwbx.Program program = new cwbx.Program(); 
       program.LibraryName = "LIBRARY"; 
       program.ProgramName = "RPGPROG"; 
       program.system = system; 

       // Sample parameter data 
       char chrValue = '1'; 
       string strValue1 = "ABC"; 
       string strValue2 = "DEF"; 
       string outp = ""; 

       // Create a collection of parameters associated with the program 
       ProgramParameters parameters = new ProgramParameters(); 

       parameters.Append("P1", cwbrcParameterTypeEnum.cwbrcInput, 1); 
       parameters["P1"].Value = chrValue; 

       parameters.Append("P2"), cwbrcParameterTypeEnum.cwbrcInput, 3); 
       parameters["P2"].Value = strValue1; 

       parameters.Append("P3"), cwbrcParameterTypeEnum.cwbrcInput, 3); 
       parameters["P3"].Value = strValue1; 

       parameters.Append("P4", cwbrcParameterTypeEnum.cwbrcOutput, 3); 


       outp = stringConverter.FromBytes(parameters["P4"].Value); 
      } 

      system.Disconnect(cwbcoServiceEnum.cwbcoServiceAll); 
      Console.WriteLine(result); 
      Console.ReadKey(); 
     } 
    } 
} 

Это должно почти сработать, вы должны быть осторожны, поскольку интерфейс dll чувствителен к ложной длине параметра. Поэтому, если вы хотите передать «ТЕКСТ» и предоставить длину текста 3, то передается только «TEX».

+0

моей целью было найти правильный синтаксис для размещенного вопроса. Однако ваш пост очень информативен и интересен, поддерживается. – ehh

0

вам следует использовать DLL Ibm поставщика данных для .net как here

Но вы можете попытаться изменить вам код

OdbcCommand cm = new OdbcCommand("{CALL RET_IMPL_STS('?','?','?','?')}", cn); 
.... 
cm.Parameters["@P4"].Direction = ParameterDirection.InputOutput; 
Смежные вопросы