Вызов одной хранимой процедуры из другой в C # - PullRequest
0 голосов
/ 08 августа 2010

У меня ошибка «Ошибка преобразования типа данных nvarchar в десятичную», когда вызов хранимой процедуры вызывает другую хранимую процедуру из C # как

cmd = new SqlCommand("tax_Base_emp", con);
cmd.CommandType = CommandType.StoredProcedure;
parm1 = new SqlParameter("@emp_code", SqlDbType.BigInt); 
parm1.Value = emp_code; 
parm1.Direction = ParameterDirection.Input; 
cmd.Parameters.Add(parm1);
parm2 = new SqlParameter("@co_id", SqlDbType.BigInt); 
parm2.Value = Settings.Default.comp_id; 
parm2.Direction = ParameterDirection.Input; 
cmd.Parameters.Add(parm2);
parm3 = new SqlParameter("@d", SqlDbType.DateTime); 
parm3.Value = Convert.ToDateTime("31/1/2010"); 
parm3.Direction = ParameterDirection.Input; 
cmd.Parameters.Add(parm3);
parm4 = new SqlParameter("@y", SqlDbType.Int); 
parm4.Value =int.Parse(textBox2.Text); 
parm4.Direction = ParameterDirection.Input; 
cmd.Parameters.Add(parm4);
parm5 = new SqlParameter("@check_month", SqlDbType.Int); 
parm5.Value =1; 
parm5.Direction = ParameterDirection.Input; 
cmd.Parameters.Add(parm5);
parm6 = new SqlParameter("@month", SqlDbType.Int); 
parm6.Value =8; 
parm6.Direction = ParameterDirection.Input; 
cmd.Parameters.Add(parm6);
SqlParameter parm7 = new SqlParameter("@indate", SqlDbType.DateTime); 
parm7.Value = Convert.ToDateTime("8/5/2010"); 
parm7.Direction = ParameterDirection.Input; 
cmd.Parameters.Add(parm7);
SqlParameter parm8 = new SqlParameter("@Sumtotal", SqlDbType.Decimal); 
parm8.Scale = 2; 
parm8.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(parm8);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
decimal tax_value = Convert.ToDecimal(cmd.Parameters["@Sumtotal"].Value);

И сохраненная процедура называется:

ALTER  PROCEDURE  Tax_Base_emp
  @emp_code bigint,
  @co_id bigint,
  @d datetime,
  @y int,
  @check_month int,
  @month int,
  @indate datetime,
  @Sumtotal decimal(8,2) output

AS
 declare  @tax_main_sal decimal(8,2)  
 declare  @tax_var_sal decimal(8,2)
 declare @salary decimal(8,2)
 declare @insh_varsalary decimal(8,2)
 declare @insh_value decimal(8,2)
 declare @vacation_value decimal(8,2)
 declare @vacation_varsalary decimal(8,2)
 declare @ded_value decimal(8,2) 
 declare @ben_value decimal(8,2) 


exec Taxable_mainsalary @emp_code,@co_id,@tax_main_sal output
exec taxable_varsalary @emp_code,@co_id, @tax_var_sal output
----taxableSalary---------------
set @salary=@tax_main_sal+@tax_var_sal
----insurance-------------------
exec  varsalary_insh @emp_code,@co_id,@d,@y, @insh_varsalary  output
exec insh_no @emp_code,@co_id,@insh_varsalary,@check_month, @insh_value output
----vacation--------------------
exec  vacation_varsalary @emp_code,@co_id,@vacation_varsalary output
exec  vacation_value @emp_code,@co_id,@y,@month,@vacation_varsalary,output
---------deduction--------------- 
exec deduction_for_tax @emp_code,@co_id,@indate,@ded_value output
-------------benifit------------
exec benfit_for_tax @emp_code,@co_id,@indate,@ben_value output
-----------------------------------NetSalary--------------------------------------------------------
 set @Sumtotal=(isnull(@salary,0)+isnull(@ben_value,0))-(isnull(@insh_value,0)+isnull(@vacation_value,0)+isnull(@ded_value,0))
return 

Ответы [ 2 ]

3 голосов
/ 08 августа 2010

Я не вижу ничего плохого в вашем C # -коде - очень сложно сказать, что может вызвать проблему. Ваш код C # просто вызывает один сохраненный процесс - это не должно быть проблемой, на самом деле.

Однако у меня есть несколько рекомендаций для вашего стиля кодирования:

  • поместите ваши SqlConnection и SqlCommand в using(....) { .... } блоки, чтобы сделать ваш код более надежным
  • старайтесь избегать указания значений свойств по умолчанию, например Direction = ParameterDirection.Input; снова и снова; .Input является значением по умолчанию - указывайте его только при отклонении от этого значения по умолчанию
  • если вы делаете одни и те же шаги снова и снова - почему бы вам не поместить это в метод и не вызывать этот метод пару раз ?? Это также избавляет вас от необходимости создавать миллиард SqlParameter объектов, которые вы затем просто выбрасываете .....

Вы бы получили что-то вроде:

public void CallStoredProc()
{
    using(SqlConnection con = new SqlConnection(.....))
    using(SqlCommand cmd = new SqlCommand("tax_Base_emp", con))
    {
       cmd.CommandType = CommandType.StoredProcedure;

       AddParameter(cmd.Parameters, "@emp_code", SqlDbType.BigInt, emp_code);
       AddParameter(cmd.Parameters, "@co_id", SqlDbType.BigInt, comp_id);
       AddParameter(cmd.Parameters, "@d", SqlDbType.DateTime, Convert.ToDateTime("31/1/2010"));
       AddParameter(cmd.Parameters, "@y", SqlDbType.Int, int.Parse(textBox2.Text));
       AddParameter(cmd.Parameters, "@check_month", SqlDbType.Int, 1);
       AddParameter(cmd.Parameters, "@month", SqlDbType.Int, 8);
       AddParameter(cmd.Parameters, "@indate", SqlDbType.DateTime, Convert.ToDateTime("8/5/2010"));

       AddOutputParameter(cmd.Parameters, "@Sumtotal", SqlDbType.Decimal, 8, 2);

       con.Open();
       cmd.ExecuteNonQuery();
       con.Close();

       decimal tax_value = Convert.ToDecimal(cmd.Parameters["@Sumtotal"].Value);
   }
}

public void AddParameter(SqlParameterCollection params, string name, SqlDbType type, object value)
{
    SqlParameter tmpParam = new SqlParameter(name, type); 
    tmpParam.Value = value; 
    params.Add(tmpParam);
}

public void AddOutputParameter(SqlParameterCollection params, string name, SqlDbType type, int precision, int scale)
{
    SqlParameter tmpParam = new SqlParameter(name, type); 
    tmpParam.ParameterDirection = Direction.Output;
    tmpParam.Precision = precision; 
    tmpParam.Scale = scale; 
    params.Add(tmpParam);
}
0 голосов
/ 08 августа 2010

Я не вижу ничего в опубликованном вами коде, который мог бы вызвать это.

Я подозреваю, что ошибка в одной из 8 хранимых процедур, которые вы вызываете, когда вы назначаете nvarcharдесятичное число.

Я бы временно закомментировал все это и просто возвратил бы фиктивное число, если это исправит его, раскомментируйте половину и попробую еще раз.Если ошибка повторяется, то вы знаете, что она в одном из тех, которые вы только что прокомментировали.т. е. выполнить бинарный поиск, чтобы найти нарушающую процедуру.

...