Возник следующий вопрос
Имеется ХП:
ALTER PROCEDURE [dbo].[spAddObjectType](
@flId as int output,
@flName as nvarchar(30),
@flDescription as nvarchar(200),
@flCount as int
)
AS
BEGIN
insert into tbObjectType(
flName,
flDescription
)
values (@flName,@flDescription)
set @flId = SCOPE_IDENTITY();
declare @temp table (ObjectId int)
DECLARE @i int = 0
WHILE @i < @flCount begin
declare @ObjectId as int
Execute spAddObject @ObjectId out, @flId, null
insert into @temp values (@ObjectId)
set @i =@i+1
end
select * from @temp as NewObjectsId
END
Возвращает таблицу и одно значение через параметр.
следующий код должен вызывать эту ХП
public List<int> AddObjectType(out int id, ObjectType objectType) {
List<int> ret = new List<int>();
using (var sqlConnection = new SqlConnection(_conString)) {
var sqlCommand = new SqlCommand("spAddObjectType", sqlConnection);
sqlCommand.CommandType=CommandType.StoredProcedure;
if (id ==null)id= -1;
sqlCommand.Parameters.Add(new SqlParameter("flId",DbType.Int32));
sqlCommand.Parameters["flId"].Direction = ParameterDirection.Output;
sqlCommand.Parameters.Add(new SqlParameter("flName", objectType.Name));
sqlCommand.Parameters.Add(new SqlParameter("flDescription", objectType.Description));
sqlCommand.Parameters.Add(new SqlParameter("flCount", 3));
try {
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
id = (int)sqlCommand.Parameters["flId"].Value;
while (sqlDataReader.Read()) {
ret.Add((int)sqlDataReader[0]);
}
} catch (Exception ex) {
throw ex;
}
}
return ret;
}
проблема: если выполняю командой
sqlCommand.ExecuteReader()
,то получаю таблицу (параметр flId не изменяется);
если выполняю
sqlCommand.ExecuteNonQuery()
,то параметр изменяется нормально (не получаю таблицы)
вопрос: Как выполнить ХП так как она есть (получить и таблицу, и параметр одновременно)
Спасибо!
У тебя процедура возвращает несколько таблиц, каждый select — новая таблица. Через ридер ты получаешь только первую таблицу. Для доступа ко все таблицам используй адаптер. Пример из msdn:
private static DataSet SelectRows(DataSet dataset,
string connectionString,string queryString)
{
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(
queryString, connection);
adapter.Fill(dataset);
return dataset;
}
}
Здравствуйте, Abay, Вы писали:
A>вопрос: Как выполнить ХП так как она есть (получить и таблицу, и параметр одновременно)
Могу предложить выполнять хранимку через EXEC, затем делать SELECT значения параметра. Примерно так:
...
var sqlCommand = new SqlCommand(
@"DECLARE @flId int;
EXEC spAddObjectType @flId, @flName, @flDescription, @flCount;
SELECT @flId",
sqlConnection);
sqlCommand.CommandType=CommandType.Text;
// Параметр flId уже не нужен
...
Получать данные будем как-то так:
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
// То что вернула хранимка
while (sqlDataReader.Read()) {
ret.Add((int)sqlDataReader[0]); }
// То что вернул SELECT @flId
sqlDataReader.NextResult();
sqlDataReader.Read();
id = (int)sqlDataReader.GetValue(0);
Все, задача решена! Всем спасибо!Pro100Oleh, совет очень помог
Вот рабочий код:
public List<int> AddObjectType(out int id, ObjectType objectType) {
var ret = new List<int>();
using (var sqlConnection = new SqlConnection(_conString)) {
var sqlCommand = new SqlCommand("spAddObjectType", sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.Add(new SqlParameter("flId", SqlDbType.Int));
sqlCommand.Parameters["flId"].Direction = ParameterDirection.Output;
sqlCommand.Parameters.Add(new SqlParameter("flName", objectType.Name));
sqlCommand.Parameters.Add(new SqlParameter("flDescription", objectType.Description));
sqlCommand.Parameters.Add(new SqlParameter("flCount", 3));
try {
sqlConnection.Open();
var adapter = new SqlDataAdapter(sqlCommand);
var dataSet = new DataSet("ds");
adapter.Fill(dataSet);
id = (int) sqlCommand.Parameters["flId"].Value;
foreach (DataRow row in dataSet.Tables[0].Rows) {
ret.Add((int) row["ObjectId"]);
}
} catch (Exception ex) {
throw ex;
}
}
return ret;
}
Здравствуйте, Pro100Oleh, Вы писали:
PO>У тебя процедура возвращает несколько таблиц, каждый select — новая таблица. Через ридер ты получаешь только первую таблицу.
Это не совсем верно