2011-08-19 6 views
5

私の会社は古い古いものを置き換える新しいインベントリプログラムを開発することになりました。申し訳ありませんが、開発者はアプリケーションをデバッグする前に残してしまいました。その結果、C#の限られた知識で2つの問題を把握しようとしていました。データ型nvarcharをアプリケーション(C#)からintに変換する際にエラーが発生しましたが、独自のSPを実行していません

アプリケーションの大部分はうまく動作しますが、技術者からインベントリを受信しようとすると、エラーが発生します(SqlExceptionはユーザーコードによって処理されませんでした - データtyoe nvarcharをintに変換するエラー)。私はコード、テーブル、ストアドプロシージャを見つめていて、問題が見つからない場合は、誰かが私がここで紛失していることを指摘してくれることを願っています。以下は、スタックトレース、C#コーディング、ストアドプロシージャ、およびテーブルです。

[SqlException (0x80131904): Error converting data type nvarchar to int.] 
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +2062078 
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +5050204 
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234 
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2275 
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +215 
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987 
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162 
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +178 
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +137 
DAL.DBManager.ExecuteNonQuery(CommandType commandType, String commandText) in C:\Users\kevin.price\Documents\Visual Studio 2010\Projects\Equip\DAL\DAL.cs:221 
Equip.EquipmentMainPage.btnReceiveProcess_Click(Object sender, EventArgs e) in C:\Users\kevin.price\Documents\Visual Studio 2010\Projects\Equip\EquipmentMainPage.aspx.cs:358 
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118 
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112 
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10 
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13 
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36 
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563 

C#コードは、ストアドプロシージャ

protected void btnReceiveProcess_Click(object sender, EventArgs e) 
    { 
     string[] lines = txtReceive.Text.Split('\n'); 

     dm.Open(); 
     for (int I = 0; I < lines.GetLength(0); I++) 
     { 
      dm.CreateParameters(9); 
      dm.AddParameters(0, "@OP", "RcvdTech"); 
      dm.AddParameters(1, "@BatchID", "{" + guid + "}"); 
      dm.AddParameters(2, "@BatchDate", DateTime.Now.Date); 
      dm.AddParameters(3, "@boxnum", lines.GetValue(I)); 
      dm.AddParameters(4, "@boxtype", Convert.ToString(BoxType(lines.GetValue(I).ToString()))); 
      dm.AddParameters(5, "@status", "RcvdTech"); 
      dm.AddParameters(6, "@modby", user); 
      dm.AddParameters(7, "@corp", null); 
      dm.AddParameters(8, "@cominvoice", null); 


      { 

      } 

      dm.ExecuteNonQuery(CommandType.StoredProcedure, "bxReceive"); 

      dm.Close(); 

      script = 
       "<script type='text/javascript'>alert('Process Complete');</script>"; 
      var page = HttpContext.Current.CurrentHandler as Page; 
      if ((!page.ClientScript.IsClientScriptBlockRegistered("alert"))) 
      { 
       page.ClientScript.RegisterClientScriptBlock(GetType(), "alert", script); 
      } 
     } 

をsnippit

ALTER PROCEDURE [dbo].[bxReceive] 
-- Add the parameters for the stored procedure here 
@OP varchar(50), @BatchID varchar(50), @BatchDate varchar(50), 
@boxnum varchar(50), @boxtype int, @status varchar(50), @modby varchar(50), @corp varchar(50), @cominvoice varchar(50) 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
Declare @msg varchar(50) 
set @boxnum = replace(@boxnum,char(13),'') 
set @BatchID = left(@BatchID,CHARINDEX(char(125),@BatchID)) 
set @msg = 'White' 

if ltrim(rtrim(@OP)) = 'RcvdTech' 
    begin 
     set @boxtype = isnull((select top 1 isnull(boxtype,9) from boxHistory where boxnum = rtrim(@boxnum) and boxtype <> 0),9) 
    end 


--Begin Try 
--begin transaction 

IF LEN(@boxnum) > 0 and (SELECT count(*)FROM dbo.bxReceived where BatchID = rtrim(@BatchID)and [boxnum] = rtrim(@boxnum) and [corp] = rtrim(@corp) and [cominvoice] = rtrim(@cominvoice)) = 0 
Begin 
INSERT INTO dbo.bxReceived 
      ([BatchID] 
      ,[BatchDate] 
      ,[boxnum] 
      ,[boxtype] 
      ,[status] 
      ,[modby] 
      ,[corp] 
      ,[cominvoice]) 

select rtrim(@BatchID), rtrim(@BatchDate),rtrim(@boxnum), @boxtype, rtrim(@status), rtrim(@modby), rtrim(@corp), rtrim(@cominvoice) 

if ltrim(rtrim(@OP)) = 'newstock' 
    begin 
     if (select COUNT(*) from boxHistory where boxnum = rtrim(@boxnum) and enddate is null) = 0 
      begin 
       INSERT INTO [boxHistory] 
       ([boxnum],[boxtype],[tech],[status],[newstatus] 
       ,[account],[startdate],[enddate],[modby],[ReqActn],[ActnReq],[corp],[cominvoice]) 

       select rtrim(@boxnum), @boxtype,0, rtrim(@status),null,null,GETDATE(), null, rtrim(@modby),null,null,@corp, @cominvoice 
      end 
     else 
      begin 
       update [boxHistory] 
        set [newstatus] = rtrim(@status), [enddate] = GETDATE() 
       where boxnum = rtrim(@boxnum) and enddate is null 

       INSERT INTO [boxHistory] 
       ([boxnum],[boxtype],[tech],[status],[newstatus] 
       ,[account],[startdate],[enddate],[modby],[ReqActn],[ActnReq],[corp],[cominvoice]) 

       select rtrim(@boxnum), @boxtype,0, rtrim(@status),null,null,GETDATE(), null, rtrim(@modby),'Y','Was active in Inventory',@corp,@cominvoice 
      end 
    end 


if ltrim(rtrim(@OP)) = 'RcvdTech' 
    begin 
     if (select COUNT(*) from boxHistory where boxnum = rtrim(@boxnum) and enddate is null) > 0 
      begin 
       update [boxHistory] 
        set [newstatus] = rtrim(@status), [enddate] = GETDATE() 
       where boxnum = rtrim(@boxnum) and enddate is null 

       INSERT INTO [boxHistory] 
       ([boxnum],[boxtype],[tech],[status],[newstatus] 
       ,[account],[startdate],[enddate],[modby],[ReqActn],[ActnReq]) 

       select rtrim(@boxnum), @boxtype,0, rtrim(@status),null,null,GETDATE(), null, rtrim(@modby),null,null 
      end 
     else 
      begin 
       INSERT INTO [boxHistory] 
       ([boxnum],[boxtype],[tech],[status],[newstatus] 
       ,[account],[startdate],[enddate],[modby],[ReqActn],[ActnReq]) 

       select rtrim(@boxnum), @boxtype,0, rtrim(@status),null,null,GETDATE(), GETDATE(), rtrim(@modby),'Y','Was not active in Inventory' 
       set @msg = 'RED' 
      end 
    end 

[dbo].[boxHistory](
[id] [bigint] IDENTITY(1,1) NOT NULL, 
[boxnum] [varchar](50) NOT NULL, 
[boxtype] [int] NULL, 
[tech] [int] NULL, 
[status] [varchar](50) NULL, 
[newstatus] [varchar](50) NULL, 
[account] [varchar](50) NULL, 
[startdate] [datetime] NULL, 
[enddate] [datetime] NULL, 
[modby] [varchar](50) NULL, 
[ReqActn] [char](1) NULL, 
[ActnReq] [varchar](50) NULL, 
[corp] [varchar](50) NULL, 
[cominvoice] [varchar](50) NULL, 


[dbo].[bxReceived](
[BatchID] [varchar](100) NULL, 
[BatchDate] [varchar](50) NULL, 
[boxnum] [varchar](50) NOT NULL, 
[boxtype] [int] NOT NULL, 
[status] [varchar](50) NULL, 
[modby] [varchar](50) NULL, 
[cominvoice] [varchar](50) NULL, 
[corp] [varchar](50) NULL 

P.S.誰でも私にどのようにプロンプ​​トを作成するか教えてもらえればboxnumがboxhistoryにない場合、boxtypeとcorpを追加するように求めるメッセージが表示されます。

事前にお問い合わせいただきありがとうございます。

[FormatException: Input string was not in a correct format.] 
System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) +9586043 
System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) +119 
System.Convert.ToInt32(String value) +48 
Equip.EquipmentMainPage.btnReceiveProcess_Click(Object sender, EventArgs e) in C:\Users\kevin.price\Documents\Visual Studio 2010\Projects\Equip\EquipmentMainPage.aspx.cs:347 
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118 
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112 
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10 
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13 
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36 
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563 
+0

[bxReceive]の@boxtypeパラメータがintを予期していて、コードが文字列を渡していますか? – JohnD

答えて

6

私の最高の推測では、あなたの問題は、この行であることを次のようになります。手順の@boxtypeで

dm.AddParameters(4, "@boxtype", Convert.ToString(BoxType(lines.GetValue(I).ToString()))); 

intとして宣言されているが、私はAddParametersのこのオーバーロードは、タイプのあなたのパラメータを行いますと信じてvarchar。私はあなたのデータが何であるかは分かりませんが、どちらか一方が間違っているようです。私は、上記の行は、おそらくそれは正確に何BoxType(lines.GetValue(I).ToString()))リターンに依存

dm.AddParameters(4, "@boxtype", Convert.ToInt32(BoxType(lines.GetValue(I).ToString()))); 

べきであると思います。 intの文字列表現の場合は、上記を使用します。私は私が私はこのエラーをデバッグ方法についてのメモを追加しようと思いました。この結論

に来たのはなぜ

dm.AddParameters(4, "@boxtype", BoxType(lines.GetValue(I).ToString())); 

:それはint型である場合、あなたは、すべての変換を必要としません将来の使用のために理解することができます。

エラーメッセージ "データ型nvarcharをintに変換中にエラーが発生しました"は、どこかでintを期待しているのにnvarcharを受け取っていることを示しています。 NvarcharsはSQLの型だけなので、SQLに何かか、データベースへの呼び出しに何かがなければならないことがわかります。

プロシージャ自体に問題があった場合は、プロシージャを他のアプリケーションからテストするときに気づいたでしょう。これは、手続きが呼び出されている最中であったに違いないことを意味します。

この時点で、パラメータリストを見て、1つのパラメータがintであることがわかります。私たちはそれからコードとちょっと前のことをチェックします。疑わしい行があります。

+0

ご回答いただきありがとうございます。私は文字列に変換されていることに気付かず、コード内をさらに見上げています。文字列としてテーブルから引っ張っているところを見ています。コードを変更してうまくいけばテストします。問題を解決してください。私はそれがどのように進むのかを知らせます。 – Kprice84

+0

それは素晴らしいです。他の人たちが指摘しているように、エラーメッセージは、見た目が正しい場所で経験豊富な人たちを指していました。私は実際に私の答えにどのように私が上記の答えに来たかをもう少し理解することができるようにエラーを見つけたことを説明するメモを追加します。 :) – Chris

+0

あなたは実際にそれから戻ってくるものを確認しましたか?エラーは、文字列が整数に変換できなかったことを示しています。それは空の文字列を返すことができるかもしれません。その場合、それをintとして解析することはできません。この場合、データベースにvarcharを渡して解析し、必要に応じてデフォルト値を設定することを心配する方がよい場合があります。 – Chris

0

私はあなたがこの1分前に求めてきました注意してくださいので、私はちょうどクイックレスポンスを投稿が、最初の明白なものをチェックするつもりです。これは単なる型キャストエラーなので、ストアドプロシージャに送られるパラメータを確認してください。それは手掛かりを提供することができます。私は今あなたのものをより徹底的に読むでしょう。

この行は文字列を渡すので、これをint.Parse( "数値文字列")に変更するか、int.TryParseを使用します。

dm.AddParameters(4, "@boxtype", Convert.ToString(BoxType(lines.GetValue(I).ToString()))); 

しかし、手続きがintを期待している(GoogleやMSDNはこれらを使用して、あなたにまともなガイドを提供します。私はあなたがこれで製材してきたと言う注意してください)。

ALTER PROCEDURE [dbo].[bxReceive] 
-- Add the parameters for the stored procedure here 
@OP varchar(50), @BatchID varchar(50), @BatchDate varchar(50), 
@boxnum varchar(50), 
@boxtype int, 
@status varchar(50), @modby varchar(50), @corp varchar(50), @cominvoice varchar(50) 
0

あなたのストアドプロシージャは、Boxtypeがintであると思っています。ただし、SqlCommandを文字列になる@BoxTypeパラメータで設定していると、ADO.NETは@ BOXTypeパラメータが型文字列であると解釈します。クエリを実行すると、@ BoxTypeがnvarcharに変換されます。 SQL Serverは、ストアドプロシージャを実行するときに、そのnvarcharをintに変換しようとします。 SQLサーバーはこれを行うことができないため、エラーが発生しています。問題の値は常にint型に変換可能であること、

dm.AddParameters(4, "@boxtype", 
     Convert.ToString(BoxType(lines.GetValue(I).ToString()))); 

もちろん、確かなので

dm.AddParameters(4, "@boxtype", 
     Convert.ToInt32(BoxType(lines.GetValue(I).ToString()))); 

へ:

基本的には、この行を変更します。 :)

0

例外は、ストアドプロシージャが数値ではない文字値をintにキャストしようとしていることを示しています。この例外は、コードではなくデータベースからのものです。

これをテストする方法は、問題を再現する一連のパラメータを使用して手動でストアドプロシージャを実行することによって、ストアドプロシージャを分解することです。私は、あなたがあなたの質問ツールに間違いを起こすことに気付くでしょう。有効な数値ではない文字列値がわかるまで、手動でクエリを実行する必要があります。

関連する問題