如何从C#中的Web服务中的存储过程获取多个输出参数?

问题描述:

我在C#中有一个Web服务,我用它来查询表,但我想创建一个WebMethod来调用存储过程并获取多个输出参数。我可以使用输出参数执行它,但当我尝试将其称为白色输出参数时,它不起作用。如何从C#中的Web服务中的存储过程获取多个输出参数?

这是一个示例,我想回复更多的2个参数。

存储过程:

CREATE OR REPLACE PROCEDURE O_CAPEREZ.GIO_SP (
    VNOMBRE IN VARCHAR2, 
    SALUDO OUT VARCHAR2) 
AS 
BEGIN 
    INSERT INTO G_PRUEBA_SP(NOMBRE) 
    VALUES (vNOMBRE); 

    SALUDO:= ('Hello: ' || vNOMBRE); 
END; 

这是我在网络服务,当我使用的输出变量,我得到这个错误执行它的代码

[HYC00] [甲骨文] [ODBC]可选功能没有实现

C#代码:

[WebMethod] 
public string AP_Data(string curp) 
{ 
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString; 

    using (OdbcConnection con = new OdbcConnection(constr)) 
    { 
      OdbcCommand cmd = new OdbcCommand("{CALL GIO_SP(?,?)}", con); 

      cmd.CommandType = System.Data.CommandType.StoredProcedure; 
      cmd.Parameters.AddWithValue("@vNOMBRE", (curp)); 
      cmd.Parameters.Add("@vNOMBRE", OdbcType.VarChar, 18); 

      cmd.Connection.Open(); 
      cmd.ExecuteNonQuery(); 

      cmd.Parameters["@SALUDO"].Direction = ParameterDirection.ReturnValue; 
      cmd.Connection.Close(); 

      string ret = Convert.ToString(cmd.Parameters["@SALUDO"].Value); 
      return ret; 
    } 
} 
+0

您需要**设置**参数的'.Direction' *** BEFORE ***调用'.ExecuteNonQuery()'! –

您必须将参数添加到即使你不打算设置有一个值列表:

cmd.Parameters.Add("@SALUDO", OdbcType.VarChar, 18).Direction = ParameterDirection.Output; 

我不知道甲骨文味道不同,但在SQL我用ParameterDirection.ReturnValue而不是ParameterDirection.Output

这里就是我如何做到这一点在MS SQL Server 2008,但注意数据类型和创建必须在同一表格中的变量lenth

的存储过程创建代码

USE DATABASE DATABASE_NAME 
GO 
CREATE PROC SP_METHOD 
@ID_CATIGORY INT, 
@NAME VARCHAR (50), 
@DESCRIPTION VARCHAR (50) 
AS 
INSERT INTO TABLE_NAME 
     ([ID_CAT] 
     ,[NAME_PRODUCT] 
     ,[DESC_PRODUCT]   
     ) 
VALUES 
     (@ID_CATIGORY 
     ,@NAME 
     ,@DESCRIPTION)   
     GO 

在C#代码

// Create SqlConnection 
     SqlConnection conn= new SqlConnection(@"Server=server_name; 
    DataBase=your_data_base_name;Integrated Security=false;User 
     Id=user_id;Password=password"); 

    // Open the Connection 
if (sqlconnection.State != ConnectionState.Open) 
     { 
      conn= .Open(); 
     } 
// execute stored_procedure method don't change this 
public void ExecuteCommand(string stored_procedure, SqlParameter[] param) 
    { 
     SqlCommand sqlcomd = new SqlCommand(); 
     sqlcomd.CommandType = CommandType.StoredProcedure; 
     sqlcomd.CommandText = stored_procedure; 
     sqlcomd.Connection = sqlconnection; 
     if (param !=null) 
     { 
      sqlcomd.Parameters.AddRange(param); 
     } 
     sqlcomd.ExecuteNonQuery(); 
    } 
     // close connection method 
     public void close_conn() 
    { 
     if (sqlconnection.State == ConnectionState.Open) 
     { 
      sqlconnection.Close(); 
     } 
    }  
     // execute and retrieving data Method  
    public void Add_product(int ID_cat ,string Name_Product,string 
    Des_Product) 
    { 
     SqlParameter[] param = new SqlParameter[3]; 

     param[0] = new SqlParameter("@ID_CAT", SqlDbType.Int); 
     param[0].Value = ID_cat; 

     param[1] = new SqlParameter("@NAME_PRODUCT", SqlDbType.VarChar, 50); 
     param[1].Value = Name_Product; 

     param[2] = new SqlParameter("@DESC_PRODUCT", SqlDbType.VarChar, 50); 
     param[2].Value = Des_Product; 

     ExecuteCommand("StoredProcedure_name", param); 
     close_conn(); 
     } 

最后你可以调用这个函数

Add_product(Convert.ToInt32(ComboBox.SelectedValue),txt_name.Text, 
    txt_desc.Text); 

如果有任何部分你不明白我知道

我见过很多方法来实现这一点。

一种方法是管道在您的存储过程中分隔您的select语句,然后使用"Value1|Value2".Split('|')[0]获取Value1。

您也可以返回一个表,而不是使用多个参数

DataTable table = new DataTable(); 
DataAdapter adapter = new DataAdapter(cmd); 
adapter.fill(table); 
return table.Rows[0]["Greeting"] + table.Rows[0]["Name"]; 

在第二个例子,只要你想,你可以返回尽可能多的“参数”,但你必须给他们以后分配给他们应有的斑点在你的代码中。

我也看到了一种XML方式来完成这个功能,但我不会在这里提供代码,因为我个人认为这不是一个很好的方法。我所看到的方式是将一堆XML属性添加到父标记中,然后稍后再回来并在代码中稍后查找每个标记的值。

在MySQL中它会是这样的

CREATE PROCEDURE O_CAPEREZ.GIO_SP (
    @vNOMBRE VARCHAR(50)) 
AS 
BEGIN 
    INSERT INTO G_PRUEBA_SP(NOMBRE) 
    VALUES (@vNOMBRE); 

    select 'Hola' as Greeting, @vNOMBRE as Name 
END 

还要注意什么Marc_s评论

您需要设置参数的.Direction拍前调用.ExecuteNonQuery()