2013-07-06 5 views
0

Я искал сеть для ответов, но снова и снова пустал.Загрузить данные хранимой процедуры в таблицу данных

Что я пытаюсь сделать: Загрузите результаты из хранимой процедуры в DataTable.

Что случилось: Я не получаю никаких строк.

Вот мой хранимый proc (SQL Server 2012). Он получает следующий автоматически увеличиваемый идентификатор таблицы, которую вы вводите, и возвращает ее.

ALTER procedure [dbo].[GET_NEXT_AUTO_ID_OF_TABLE] 
    @TABLE_NAME nvarchar(128), 
    @NEXT_ID int output 
as 

declare @latest_id int, @row_count int 
    begin 
     set @latest_id = (select IDENT_CURRENT(@TABLE_NAME)) 
    end 
    if @latest_id = 1 
    begin 
    declare @lRowCountSql nvarchar(1000) 
    set @lRowCountSql = N'select @row_count = count(*) from ' + @TABLE_NAME 
    exec sp_executesql @lRowCountSql, N'@row_count int out', @row_count out 

    if @row_count > 0 
     set @next_id = @latest_id + 1 
    else 
     set @next_id = @latest_id 
end 
else 
    set @next_id = @latest_id + 1 
return 

Является ли проблема моей программой (я плохо разбираюсь в sql)? Когда я тестирую proc на SQL Server, я получаю ожидаемый результат. Но не из моего C# код:

 List<SqlParameter> aSqlParams = new List<SqlParameter>(); 
     aSqlParams.Add(new SqlParameter("@TABLE_NAME", "your table name") { Direction = System.Data.ParameterDirection.Input, SqlDbType = System.Data.SqlDbType.NVarChar }); 
     aSqlParams.Add(new SqlParameter() { ParameterName = "@NEXT_ID", Direction = System.Data.ParameterDirection.Output, SqlDbType = SqlDbType.Int }); 
     DataTable lDt = SQLServerUtils.ExecuteStoredProc("GET_NEXT_AUTO_ID_OF_TABLE", aSqlParams); 
     int lNextID = lDt.Rows[0].Field<int>("NEXT_ID"); 

    public static DataTable ExecuteStoredProc(string aProcName, List<SqlParameter> aSqlParams) 
    { 
     DataTable lResults = new DataTable(); 

     using (SqlConnection conn = new SqlConnection(DatabaseConnectionString)) 
     { 
      SqlCommand cmd = new SqlCommand(aProcName, conn); 
      cmd.CommandType = CommandType.StoredProcedure; 

      if (aSqlParams != null) 
       foreach (SqlParameter lP in aSqlParams) 
        cmd.Parameters.Add(lP); 
      conn.Open(); 
      SqlDataAdapter adapter = new SqlDataAdapter(cmd); 
      adapter.Fill(lResults); 
     } 
     return lResults; 
    } 
+0

Вся причина для этого сложного пути, чтобы получить следующий идентификатор, потому что, если таблица пустой IDENT_CURRENT равен 1, но если есть одна строка, IDENT_CURRENT также равно 1. Поэтому, если я использую IDENT_CURRENT +1 для пустой таблицы, это будет означать, что next_id равно 2, что явно не так. – Divan

ответ

0

параметр вывода возвращается сам по себе, не входит в DataTable.
Я думаю, вам нужна другая процедура, которая выполняет такого рода запрос,

public static int ExecuteOutputIntParam(string aProcName, string outputParamName, List<SqlParameter> aSqlParams) 
{ 
    int outValue = -1; 
    using (SqlConnection conn = new SqlConnection(DatabaseConnectionString)) 
    { 
     conn.Open(); 
     SqlCommand cmd = new SqlCommand(aProcName, conn); 
     cmd.CommandType = CommandType.StoredProcedure; 

     if (aSqlParams != null) 
      foreach (SqlParameter lP in aSqlParams) 
       cmd.Parameters.Add(lP); 

     int result = cmd.ExecuteNonQuery(); 

     if (aSqlParams != null) 
     { 
      outValue = Convert.ToInt32(aSqlParams[outputParamName].Value); 

     } 
    } 
    return outValue; 
} 

EDIT я копировать/вставить ваш пример, и я не заметил, что вы полагаетесь на SqlDataAdapter, чтобы открыть/закрыть связь. В моем примере подключение должно быть открыто открыто

+0

Спасибо за усилие, но нет сигары. 'int result = cmd.ExecuteNonQuery();' дает -1 – Divan

+0

Хорошо, но значение параметра? – Steve

+0

Кроме того, я не уверен, что вы можете использовать этот синтаксис в storeprocedure 'set @latest_id = (выберите IDENT_CURRENT (@TABLE_NAME)) ' Параметр не может использоваться для замены имени таблицы или имени поля без использования динамического sql, поскольку вы сделать позже – Steve

0

Фокус в том, что значение, которое я хочу, возвращается внутри параметра out. Фиксированный код выглядит следующим образом ...

SQL прок:

ALTER procedure [dbo].[GET_NEXT_AUTO_ID_OF_TABLE] 
    @TABLE_NAME nvarchar(128), 
    @NEXT_ID int output 
as 

declare @latest_id int, @row_count int 
begin 
    set @latest_id = (select IDENT_CURRENT(''[email protected]_NAME+'')) 
end 
if @latest_id = 1 
    begin 
     declare @lRowCountSql nvarchar(1000) 
     set @lRowCountSql = N'select @row_count = count(*) from ' + @TABLE_NAME 
     exec sp_executesql @lRowCountSql, N'@row_count int out', @row_count out 

     if @row_count > 0 
      set @next_id = @latest_id + 1 
     else 
      set @next_id = @latest_id 
    end 
else 
    set @next_id = @latest_id + 1 
return 

C#:

public static int GetNextIdOfTable(string aTableName) 
    { 
     int lNextID = 0; 

     using (SqlConnection conn = new SqlConnection(DatabaseConnectionString)) 
     { 
      SqlCommand cmd = new SqlCommand("GET_NEXT_AUTO_ID_OF_TABLE", conn); 
      cmd.CommandType = CommandType.StoredProcedure; 

      cmd.Parameters.Add(new SqlParameter("@TABLE_NAME", aTableName) { Direction = System.Data.ParameterDirection.Input, SqlDbType = System.Data.SqlDbType.NVarChar }); 
      cmd.Parameters.Add(new SqlParameter() { ParameterName = "@NEXT_ID", Direction = System.Data.ParameterDirection.Output, SqlDbType = SqlDbType.Int }); 

      conn.Open(); 
      cmd.ExecuteReader(); 

      if (cmd.Parameters["@NEXT_ID"] != null && cmd.Parameters["@NEXT_ID"].Value != DBNull.Value) 
       return int.Parse(cmd.Parameters["@NEXT_ID"].Value.ToString()); 
     } 
     return lNextID; 
    } 
Смежные вопросы