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

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

ただいまの
回答率

90.48%

  • C#

    7472questions

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

  • SQL Server

    605questions

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

  • Visual Studio 2012

    91questions

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

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,268

hinatti

score 6

前提・実現したいこと

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

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

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

該当のソースコード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Printing;

namespace ProductDisplay
{
    public partial class FormProductDisplay : Form
    {
        /// <summary>
        /// product_table読み取りの現在位置
        /// </summary>
        private int location;

        /// <summary>
        /// SQLserver接続変数
        /// </summary>
        private SqlConnection connection;

        /// <summary>
        /// ページカウント変数
        /// </summary>
        private int page = 1;

        /// <summary>
        /// 印刷する最大ページ数
        /// </summary>
        private const int MAX_PAGE = 200;

        /// <summary>
        /// ProductDisplayフォームのコンストラクタ
        /// </summary>
        public FormProductDisplay()
        {
            InitializeComponent();
        }

        /// <summary>
        /// FormProductDisplayのイベントハンドラ
        /// DBに接続してseihin.txtをINSERTする
        /// </summary>
        /// <param name="sender">使用しない</param>
        /// <param name="e">使用しない</param>
        private void FormProductDisplay_Load(object sender, EventArgs e)
        {
            try
            {
                using (connection = new SqlConnection(Properties.Settings.Default.ConnectionString))
                {
                    string sql = @"
                        INSERT INTO product_table (
                            product_id,
                            basic_order_lot,
                            product_code,
                            chassis_number,
                            assembled_ymd,
                            assembled_hms,
                            struct_number,
                            yyyymm
                        )
                        VALUES (
                            @product_id,
                            @basic_order_lot,
                            @product_code,
                            @chassis_number,
                            @assembled_ymd,
                            @assembled_hms,
                            @struct_number,
                            @yyyymm
                        );
                        ";

                    connection.Open();
                    SqlCommand command = new SqlCommand(sql, connection);
                    try
                    {
                        StreamReader read = new StreamReader("seihin.txt");
                        try
                        {
                            string line;
                            while ((line = read.ReadLine()) != null)
                            {
                                command.Parameters.Add(new SqlParameter("@product_id", line));
                                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();
                            }
                            read.Close();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("ファイルの読み込みに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            System.Diagnostics.Debug.WriteLine(ex.ToString());
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("ファイルを開くのに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        System.Diagnostics.Debug.WriteLine(ex.ToString());
                    }
                    connection.Close();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("データベースに接続出来ませんでした。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }

補足情報(言語/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)になってます

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • sazi

    2017/09/07 18:26

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

    キャンセル

  • hinatti

    2017/09/08 09:03

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

    キャンセル

  • sazi

    2017/09/08 09:07

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

    キャンセル

  • hinatti

    2017/09/08 09:10

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

    キャンセル

回答 3

checkベストアンサー

+1

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

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/08 09:06

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

    キャンセル

  • 2017/09/08 09:13

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

    キャンセル

  • 2017/09/08 13:33

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

    キャンセル

  • 2017/09/08 13:41

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

    キャンセル

  • 2017/09/08 16:16

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

    キャンセル

  • 2017/09/08 16:27

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

    キャンセル

  • 2017/09/08 16:41

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

    キャンセル

  • 2017/09/08 16:52

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

    キャンセル

0

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

5852232    2A11B5632ZABFA157220000825 18:08:57  8D11080200008

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/08 09:08

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

    キャンセル

0

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

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

                            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/08 09:07

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

    キャンセル

  • 2017/09/08 09:16

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

    キャンセル

  • 2017/09/08 09:19

    Textfieldparameterではなくて
    TextFieldParserですよ。

    キャンセル

  • 2017/09/08 09:21

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

    キャンセル

  • 2017/09/08 09:21

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

    キャンセル

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

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7472questions

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

  • SQL Server

    605questions

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

  • Visual Studio 2012

    91questions

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