Мой опыт также связан с SQL Server, и мне пришлось побаловаться с Oracle, поэтому я чувствую вашу боль.У Oracle разные языковые контексты (я уверен, что есть лучший способ описать это), и не все может быть сделано в любом контексте, как в SQL Server.
Хорошая новость заключается в том, что хотя вы должнынапример, чтобы заставить его работать в SQL Developer, могут потребоваться операторы PRINT
, реализация поставщика ADO.NET пакета Oracle.ManagedDataAccess
довольно хороша для того, чтобы сделать SYS_REFCURSOR
довольно простым в работе.
Начиная схранимая процедура, это довольно просто.Откройте выходной курсор CUR
и дайте ему прочитать результаты нужного вам запроса.(Возможно, вы захотите / должны указать владельца и / или имя пакета с именем процедуры.)
CREATE OR REPLACE PROCEDURE MY_GET_USERS
(
CUR OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN CUR FOR
SELECT
USERNAME,
USER_ID,
PASSWORD,
ACCOUNT_STATUS,
LOCK_DATE,
EXPIRY_DATE,
DEFAULT_TABLESPACE,
TEMPORARY_TABLESPACE,
CREATED,
PROFILE,
INITIAL_RSRC_CONSUMER_GROUP,
EXTERNAL_NAME,
PASSWORD_VERSIONS,
EDITIONS_ENABLED,
AUTHENTICATION_TYPE
from
dba_users;
END;
На стороне C # вам просто нужно добавить параметр RefCursor
в OracleCommand
объект с указанным правильным типом параметра.
DataSet ds = new DataSet();
using (OracleCommand command = conn.CreateCommand())
{
command.CommandText = "MY_GET_USERS";
command.CommandType = CommandType.StoredProcedure;
var curParameter = command.Parameters.Add(new OracleParameter()
{
ParameterName = "CUR",
Direction = ParameterDirection.Output,
OracleDbType = OracleDbType.RefCursor // NOT OracleDbTypeEx
});
command.ExecuteNonQuery();
OracleDataAdapter adapter = new OracleDataAdapter();
adapter.Fill(ds, (OracleRefCursor)curParameter.Value);
}
Может показаться странным использовать ExecuteNonQuery
для получения набора результатов, но результаты находятся в выходном параметре, а не в наборе результатов того же типа, что и вы.можно было бы позвонить ExecuteReader
с SQL Server.
Обратите внимание на комментарий о свойствах OracleDbType
и OracleDbTypeEx
.Если вы установите свойство OracleDbTypeEx
, свойство Value
будет установлено на объект OracleDataReader
.При установке свойства OracleDbType
для свойства Value
будет установлен объект OracleRefCursor
, который adapter.Fill
использует выше.Любой из них можно использовать, если вы хотите получить объект OracleDataReader
и прочитать результаты самостоятельно.
// OracleDbType
using (var reader = ((OracleRefCursor)curParameter.Value).GetDataReader())
// OracleDbTypeEx
using (var reader = ((OracleDataReader)curParameter.Value))