0

25000 個のテキスト ファイルを含むフォルダーがあり、これらのファイルを読み込んで単語を表に配置したいと考えています。 25000.txt に続きます。各テキスト ファイルには、次の形式の単語が含まれています。

sample contents of my file
apple
cat
rat
shoe

単語は他のテキストファイルでも繰り返される可能性があります。テキストファイルを読み取って、繰り返される単語と繰り返されない単語を識別し、次の形式で Sqlserver のデータベースに挿入できる ac# コードが必要です。

keyword    document name
cat        1.txt,2.txt,3.txt
rat        4.txt,1.txt
fish       5.txt

`

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;


using System.Windows.Forms;

using System.IO;

using System.Data.SqlClient;



namespace RAMESH
 {
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {

    }

    private void button2_Click(object sender, EventArgs e)
    {

        string[] files = Directory.GetFiles(textBox1.Text, "*.txt");
        int i;
        string sqlstmt,str;
        SqlConnection con = new SqlConnection("data source=dell-pc\\sql1; initial         catalog=db; user id=sa; password=a;");
        SqlCommand cmd;
        sqlstmt = "delete from Items";
        cmd = new SqlCommand(sqlstmt, con);
        con.Open();
        cmd.ExecuteNonQuery();
        for (i = 0; i < files.Length; i++)
        {
            StreamReader sr = new StreamReader(files[i]);
            FileInfo f = new FileInfo(files[i]);
            string fname;
            fname = f.Name;
            fname = fname.Substring(0, fname.LastIndexOf('.'));
            //MessageBox.Show(fname);
            while ((str = sr.ReadLine()) != null)
            {
                int nstr=1;
                //int x,y;
                //for (x = 0; x < str.Length; x++)
                //{ 
                //    y = Convert.ToInt32(str.Substring(x,1));
                //    if ((y < 48 && y > 75) || (y < 65 && y > 97) || (y < 97 && y > 122)) ;
                //}
                sqlstmt = "insert into Items values('" + str + "','" + fname + "')";
                cmd = new SqlCommand(sqlstmt, con);                    
                try
                {
                    cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    sqlstmt = "update Items set docname=docname + '," + fname + "'   where itemname='" + str + "'";
                    cmd = new SqlCommand(sqlstmt, con);
                    cmd.ExecuteNonQuery();
                }
            }
            sr.Close();
        }
        MessageBox.Show("keywords added successfully");
        con.Close();
    }
}

} `

4

2 に答える 2

1

何よりもまず、データベースにストアド プロシージャを追加して、更新または挿入のロジックを分離します。

CREATE PROCEDURE UpsertWords
@word nvarchar(MAX), @file nvarchar(256)
as

    Declare @cnt integer
    Select @cnt = Count(*) from Items where ItemName = @word
    if @cnt = 0 
        INSERT INTO Items (@word, @file)
    else
        UPDATE Items SET docname = docname + ',' + @file where ItemName = @word

これで、コードを大幅に簡素化できます

.....

// Build the command just one time, outside the loop,
// make it point to the stored procedure above
cmd = new SqlCommand("UpsertWords", con);
cmd.CommandType = CommandType.StoredProcedure;                    

// Create dummy parameters, the actual value is supplied inside the loop
cmd.Parameters.AddWithValue("@word", string.Empty);
cmd.Parameters.AddWithValue("@file", string.Empty);

// Now loop on every file
for (i = 0; i < files.Length; i++)
{
    // Open and read all the lines in the current file
    string[] lines = File.ReadAllLines(files[i]);

    // Get only the filename part without the extension
    string fname = Path.GetFileNameWithoutExtension(files[i])

    // In case of just one line per file, this loop will execute just one time
    // however we also could handle more than one line per file
    foreach(string line in lines)
    {
        // Set the actual value of the parameters created outside the loop
        cmd.Parameters["@word"] = line;
        cmd.Parameters["@file"] = fname;
        // Run the insert or update (the logic is inside the storedprocedure)
        cmd.ExecuteNonQuery();
    }

この時点では、行が単一の単語で構成されているのか、それとも文字 (タブ、コンマ、セミコロン) で区切られた複数の単語があるのか​​は明確ではありません。その場合、文字列と別のループを分割する必要があります。

ただし、データベース スキーマが間違っていることがわかりました。ファイルに表示されるすべての単語に対して新しい行を追加することをお勧めします。このようにして、次のような単純なクエリ

SELECT  docname from Items where itemname = @word 

大きなパフォーマンスの問題なしにすべてのファイルを表示し、より検索可能なデータベースを使用できます。
または、単語の出現をカウントする必要がある場合

SELECT ItemName, COUNT(ItemName) as WordCount 
FROM Items 
GROUP BY ItemName 
ORDER BY Count(ItemName) ASC
于 2013-03-30T12:19:26.067 に答える