none
使用EnterpriseLibrary4.1的GenericDatabase時,在GetStoredProcCommand發生的問題 RRS feed

  • 問題

  • 程式的功能是用來呼叫Oracle的Stored Procedure,使用Datareader來接回傳的Cursor,

    所以寫了

    Imports System.Data.Common
    Imports Microsoft.Practices.EnterpriseLibrary.Data
    Imports Microsoft.Practices.EnterpriseLibrary.Common

                Dim DB As Database = DatabaseFactory.CreateDatabase ("DBCS")
                Dim cmd As DbCommand = Nothing
                Dim strSQL As String = String.Empty
                Dim dr As IDataReader = Nothing

                strSQL = "getUserData"
                cmd = DB.GetStoredProcCommand(strSQL, "L", "20100712", "20100712", DBNull.Value)
                dr = DB.ExecuteReader(cmd)

    使用以上做法可以順利接回Datareader,但是要改成共用的組態檔,其中會放置連線字串,所以程式寫法改為,

                Dim DB As Database = New GenericDatabase (ConfigReader.GetConnectionStrings("DBCS"), System.Data.OracleClient.OracleClientFactory.Instance)
                Dim cmd As DbCommand = Nothing
                Dim strSQL As String = String.Empty
                Dim dr As IDataReader = Nothing

                strSQL = "getUserData"
                cmd = DB.GetStoredProcCommand(strSQL, "L", "20100712", "20100712", DBNull.Value)
                dr = DB_EBSAP.ExecuteReader(cmd)

    當執行到cmd = DB.GetStoredProcCommand的時候發生了,以下錯誤
    Parameter discovery is not supported for connections using GenericDatabase. You must specify the parameters explicitly, or configure the connection to use a type deriving from Database that supports parameter discovery.

    請問該如何解決這個錯誤呢?謝謝.

     

    環境WindowsXP,VS2008,Oracle 10g DB,EnterpriseLibrary(4.1),主控台應用程式.

     

    2010年11月3日 上午 07:18

解答

  • 把這一行:

    cmd = DB.GetStoredProcCommand(strSQL, "L", "20100712", "20100712", DBNull.Value)

    改成:

    cmd = DB.GetStoredProcCommand(strSQL)

    再自行將參數塞入cmd的Parameters集合

    • 已標示為解答 Wallace528 2010年11月4日 上午 06:23
    2010年11月4日 上午 02:47
  • 感謝Tihs的提醒,指引了另一條路,

    小弟改成下述方式就可以執行了,

        Dim cmd As DbCommand
        Dim strSQL As String = String.Empty
        Dim dr As IDataReader
        cmd = DB.GetSqlStringCommand(strSQL)
        DB.AddInParameter(cmd, "p1", DbType.String, "L")
        DB.AddInParameter(cmd, "p2", DbType.String, "20100712")
        DB.AddInParameter(cmd, "p3", DbType.String, "20100712")
        DB.AddInParameter(cmd, "Return_Cursor", DbType.Object, DBNull.Value)
        cmd.Parameters.Add(New OracleParameter("Return_Cursor", OracleType.Cursor, 0, ParameterDirection.Output, True, 0, 0, String.Empty, DataRowVersion.Current, Convert.DBNull))

        dr = DB.ExecuteReader(cmd)
        result = DataExtension.ConvertDataReaderToDataTable(dr)

    不知道會不會產生其他的問題呢,感謝幫忙:D

     

    • 已標示為解答 Wallace528 2010年11月4日 上午 06:23
    2010年11月4日 上午 06:23

所有回覆

  • 把這一行:

    cmd = DB.GetStoredProcCommand(strSQL, "L", "20100712", "20100712", DBNull.Value)

    改成:

    cmd = DB.GetStoredProcCommand(strSQL)

    再自行將參數塞入cmd的Parameters集合

    • 已標示為解答 Wallace528 2010年11月4日 上午 06:23
    2010年11月4日 上午 02:47
  • Tihs您好,感謝您的答覆,
    Stored Procedure的語法如下,

    CREATE OR REPLACE PROCEDURE getUserData
    (
      p1 IN VARCHAR2,
      p2 IN VARCHAR2,
      p3 IN VARCHAR2,
      Return_Cursor OUT SYS_REFCURSOR
    ) AS
    BEGIN
      OPEN Return_Cursor FOR
      SELECT field1, field2 from UserData
      where condition;      
    END;
    /

    因為要接回傳的Cursor,一開始是始用此方式
        cmd = DB.GetSqlStringCommand(strSQL)
        DB.AddInParameter(cmd, "p1", DbType.String, "L")
        DB.AddInParameter(cmd, "p2", DbType.String, "20100712")
        DB.AddInParameter(cmd, "p3", DbType.String, "20100712")
        DB.AddInParameter(cmd, "Return_Cursor", DbType.Object, DBNull.Value)
    但是會發生
    PLS-00306: wrong number or types of arguments in call to 'getUserData'

    後來才改用此方式,才可以正常的加入SP的參數,所以是使用這個方式
    cmd = DB.GetStoredProcCommand(strSQL, "L", "20100712", "20100712", DBNull.Value)


    您提到的,"再自行將參數塞入cmd的Parameters集合",如果是要接回Cursor的話,該如何撰寫呢?謝謝.

     

    2010年11月4日 上午 03:56
  • 感謝Tihs的提醒,指引了另一條路,

    小弟改成下述方式就可以執行了,

        Dim cmd As DbCommand
        Dim strSQL As String = String.Empty
        Dim dr As IDataReader
        cmd = DB.GetSqlStringCommand(strSQL)
        DB.AddInParameter(cmd, "p1", DbType.String, "L")
        DB.AddInParameter(cmd, "p2", DbType.String, "20100712")
        DB.AddInParameter(cmd, "p3", DbType.String, "20100712")
        DB.AddInParameter(cmd, "Return_Cursor", DbType.Object, DBNull.Value)
        cmd.Parameters.Add(New OracleParameter("Return_Cursor", OracleType.Cursor, 0, ParameterDirection.Output, True, 0, 0, String.Empty, DataRowVersion.Current, Convert.DBNull))

        dr = DB.ExecuteReader(cmd)
        result = DataExtension.ConvertDataReaderToDataTable(dr)

    不知道會不會產生其他的問題呢,感謝幫忙:D

     

    • 已標示為解答 Wallace528 2010年11月4日 上午 06:23
    2010年11月4日 上午 06:23