質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio 2012

Microsoft Visual Studio 2012は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2010の次のバージョンです

Q&A

解決済

3回答

2998閲覧

テキストファイルをデータベースに登録したい

hinatti

総合スコア14

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio 2012

Microsoft Visual Studio 2012は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2010の次のバージョンです

0グッド

0クリップ

投稿2017/09/07 09:11

編集2017/09/08 00:36

###前提・実現したいこと
5852232 2A11B5632ZABFA157220000825 18:08:57 8D11080200008
上記のようなデータが1万件あるテキストファイルをデータベースに登録したいです。
1行ずつテキストファイルを読み取ってproduct_tableにINSERTしようとしてます。
SQLに触るのは初めてで右も左も分からない状態です…
何卒ご教示お願いします…

###発生している問題・エラーメッセージ

System.Data.SqlClient.SqlException (0x80131904): 文字列データまたはバイナリ データが切り捨てられます。 場所 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()

###該当のソースコード

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Data.SqlClient; 6using System.Drawing; 7using System.Linq; 8using System.Text; 9using System.Threading.Tasks; 10using System.Windows.Forms; 11using System.IO; 12using System.Drawing.Printing; 13 14namespace ProductDisplay 15{ 16 public partial class FormProductDisplay : Form 17 { 18 /// <summary> 19 /// product_table読み取りの現在位置 20 /// </summary> 21 private int location; 22 23 /// <summary> 24 /// SQLserver接続変数 25 /// </summary> 26 private SqlConnection connection; 27 28 /// <summary> 29 /// ページカウント変数 30 /// </summary> 31 private int page = 1; 32 33 /// <summary> 34 /// 印刷する最大ページ数 35 /// </summary> 36 private const int MAX_PAGE = 200; 37 38 /// <summary> 39 /// ProductDisplayフォームのコンストラクタ 40 /// </summary> 41 public FormProductDisplay() 42 { 43 InitializeComponent(); 44 } 45 46 /// <summary> 47 /// FormProductDisplayのイベントハンドラ 48 /// DBに接続してseihin.txtをINSERTする 49 /// </summary> 50 /// <param name="sender">使用しない</param> 51 /// <param name="e">使用しない</param> 52 private void FormProductDisplay_Load(object sender, EventArgs e) 53 { 54 try 55 { 56 using (connection = new SqlConnection(Properties.Settings.Default.ConnectionString)) 57 { 58 string sql = @" 59 INSERT INTO product_table ( 60 product_id, 61 basic_order_lot, 62 product_code, 63 chassis_number, 64 assembled_ymd, 65 assembled_hms, 66 struct_number, 67 yyyymm 68 ) 69 VALUES ( 70 @product_id, 71 @basic_order_lot, 72 @product_code, 73 @chassis_number, 74 @assembled_ymd, 75 @assembled_hms, 76 @struct_number, 77 @yyyymm 78 ); 79 "; 80 81 connection.Open(); 82 SqlCommand command = new SqlCommand(sql, connection); 83 try 84 { 85 StreamReader read = new StreamReader("seihin.txt"); 86 try 87 { 88 string line; 89 while ((line = read.ReadLine()) != null) 90 { 91 command.Parameters.Add(new SqlParameter("@product_id", line)); 92 command.Parameters.Add(new SqlParameter("@basic_order_lot", line)); 93 command.Parameters.Add(new SqlParameter("@product_code", line)); 94 command.Parameters.Add(new SqlParameter("@chassis_number", line)); 95 command.Parameters.Add(new SqlParameter("@assembled_ymd", line)); 96 command.Parameters.Add(new SqlParameter("@assembled_hms", line)); 97 command.Parameters.Add(new SqlParameter("@struct_number", line)); 98 command.Parameters.Add(new SqlParameter("@yyyymm", line)); 99 command.ExecuteNonQuery(); 100 } 101 read.Close(); 102 } 103 catch (Exception ex) 104 { 105 MessageBox.Show("ファイルの読み込みに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); 106 System.Diagnostics.Debug.WriteLine(ex.ToString()); 107 } 108 } 109 catch (Exception ex) 110 { 111 MessageBox.Show("ファイルを開くのに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); 112 System.Diagnostics.Debug.WriteLine(ex.ToString()); 113 } 114 connection.Close(); 115 } 116 } 117 catch (Exception ex) 118 { 119 MessageBox.Show("データベースに接続出来ませんでした。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); 120 System.Diagnostics.Debug.WriteLine(ex.ToString()); 121 } 122 }

###補足情報(言語/FW/ツール等のバージョンなど)
product_tableの型はproduct_idがvarchar(11),basic_order_lotがvarchar(8),product_codeがvarchar(6),chassis_numberがvarchar(4),assembled_ymdがdate,assembled_hmsがtime(7),struct_numberがvarchar(7),yyyymmがchar(6)になってます

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2017/09/07 09:26

1度きりの処理ですか?それともバッチ的な業務プログラムですか?
hinatti

2017/09/08 00:03

返信遅れてしまいました… 1度きりの処理です
sazi

2017/09/08 00:07

データ移行的なことであれば、プログラミングせずに行える方法もあります。そのデータを.csvに変更してエクセルで開けますか?
hinatti

2017/09/08 00:10

プログラミングして登録しないとダメなんですよね…
guest

回答3

0

ベストアンサー

エラーは、格納しようとしてるテーブルの属性と合っていないからだと思われます。

INSERTしようとしている、product_tableのレイアウトは
① product_id varchar(11)
② basic_order_lot varchar(8)
③ product_code varchar(6)
④ chassis_number varchar(4)
⑤ assembled_ymd date
⑥ assembled_hms time(7)
⑦ struct_number varchar(7)
⑧ yyyymm char(6)
ですよね。※⑥はtime(11)とあったが誤記では?

一方、テキストファイルは固定長で、以下のレイアウトに見えます。
-----①----------②--------③-----④-----⑤----------⑥---------⑦-------⑧---
+---------++--------++-----++--++--------++-------+-+-------++-----+
5852232 2A11B5632ZABFA157220000825 18:08:57 8D11080200008

(それぞれの桁数):①11, ②8, ③6, ④4, ⑤8, ⑥8, ⑦7, ⑧6
※⑥は前後の空白を含めると10桁

line = read.ReadLine()で取得した上記の1行を、レイアウトに合わせた整形を行わずに、そのまま移送しているから桁溢れしています。
Substring()で分割して取得し、⑤⑥はそれぞれ日付型と時刻型に変換してパラメータに設定してみて下さい。
※パラメータについては型の指定も必要ですが、ループの外でADDしないと駄目じゃないかな。

投稿2017/09/07 16:02

編集2017/09/08 00:39
sazi

総合スコア25195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hinatti

2017/09/08 00:06

返信遅れてしまいました… product_idに1行分が入っていたのは分かっていたのですがどうやって分割するのか分からず悩んでました… 回答ありがとうございます、試してみます!
hinatti

2017/09/08 00:13

すみませんtime(11)間違いでtime(7)でした…
hinatti

2017/09/08 04:33

INSERT出来ました! ただパラメータをループの外で設定するとテキストファイルの最後の行しかテーブルにINSERT出来ていないです…
sazi

2017/09/08 04:41

そうでしたか、同じパラメータ名で追加するとエラーになると思ったのですが、それは自動的に上書きされているんでしょうね。
hinatti

2017/09/08 07:16

ループの中でパラメータ設定するとsaziさんの仰る通りエラーなりますね… 外に出すと1列分しか追加されないてないのでエラー出さないっぽいです。
sazi

2017/09/08 07:27

パラメータの追加はループの外で行う必要がありますけど、値のセットはループの中ですよ。 ループの外側では値はセットする必要はありません。 ループ内では、 command.Parameters["@product_id"].Value = line.Substring(0,10); みたいになるんじゃないでしょうか。
hinatti

2017/09/08 07:41

あ、なるほど… command.Parameters.Add(new SqlParameter("@product_id", connection)); パラメータの追加とはこんな感じでインスタンス初期化してあげればいいんですかね…?
hinatti

2017/09/08 07:52

ようやくINSERT出来ました…! 何から何まで本当にありがとうございました…! また何かあればよろしくお願い致します!
guest

0

上記回答の補足となりますが、原因箇所は以下の部分です。
エラーの原因は、上で説明されているとおりです。

SqlParameterにセットする前に、何らかの方法でデータを項目単位に分割する必要があります。
今回のケースで使えるかはわかりませんが、.NETにはTextFieldParserクラスが用意されており、CSVデータ等を簡単に配列化できます。

C#

while ((line = read.ReadLine()) != null) //line変数に1業の内容を全て格納している

//line -> 5852232 2A11B5632ZABFA157220000825 18:08:57 8D11080200008
{
command.Parameters.Add(new SqlParameter("@product_id", line)); // @product_idにlineの値(5852232 2A11B5632ZABFA157220000825 18:08:57 8D11080200008)をセットしている。以下同じ。
command.Parameters.Add(new SqlParameter("@basic_order_lot", line));
command.Parameters.Add(new SqlParameter("@product_code", line));
command.Parameters.Add(new SqlParameter("@chassis_number", line));
command.Parameters.Add(new SqlParameter("@assembled_ymd", line));
command.Parameters.Add(new SqlParameter("@assembled_hms", line));
command.Parameters.Add(new SqlParameter("@struct_number", line));
command.Parameters.Add(new SqlParameter("@yyyymm", line));
command.ExecuteNonQuery();
}

投稿2017/09/07 15:30

hakkun

総合スコア25

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hinatti

2017/09/08 00:07

Textfieldparameterとかあるんですね… こちらも調べて試してみます、回答補足ありがとうございます!
sazi

2017/09/08 00:16

javaならありましたけど、.NET で Textfieldparameterというのが探しきれません。 文献を教えて貰えますか。
Kunihiro_Narita

2017/09/08 00:19

Textfieldparameterではなくて TextFieldParserですよ。
sazi

2017/09/08 00:21

失礼しました。質問者さんのコメントで検索してました。
hinatti

2017/09/08 00:21

あ、勘違いしてました ありがとうございます。
guest

0

seihin.txtファイルの中身は、例えば下記であるので

5852232 2A11B5632ZABFA157220000825 18:08:57 8D11080200008

タブ区切りなのか、固定長区切りなのかわかりませんが
見た目では4項目のデータが入っているように見えます。

一方、select文からは、8項目のデータをセットする必要があります。

現在のソースでは、select文の1項目に対して、ファイルの1行全部(4項目全部)を
セットしているように見えます。

まずは、ファイルの1行を特定の区切り方法で区切り、項目毎に分けてください。
それをselect文の各項目にセットする形になります。

投稿2017/09/07 10:30

kikukiku

総合スコア514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hinatti

2017/09/08 00:08

返信遅れてしまいました… やはり分割しないとダメなんですね… 回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問