C# DB 파일 읽어 엑셀에 저장하기

JungWooLee·2022년 9월 21일
0

C#

목록 보기
1/2

프로젝트 개요

  1. 세무 법인 등에서 쓰이는 회계 관리시스템에서 수작업으로 ERP 를 통하여 엑셀로 작성하고 있음
  2. 같은 템플릿이더라도 회사마다 수당 정책이 다르며 책정되는 시급또한 달랐음
  3. 내부 DB를 보려하여도 암호화 되어있어 접근할 수 없음

1. DB 복호화후 byte array를 파일로 저장하기

				string[] _files	= Directory.GetFiles(_folderPath, "*.DBS");
				foreach (var _file in _files)
				{
					FileInfo _fi			= new FileInfo(_file);
					byte[] _encrypted		= File.ReadAllBytes(_file);

					byte[] _decrypted		= _semu.Decrypt(_encrypted);

					string _filePath		= _fi.FullName.Replace(".DBS", ".DB");
					File.WriteAllBytes(_filePath, _decrypted);
				}

DB 복호화 이 후 해당 경로에 DB extension 으로 따로 저장하였다

2. 급여관리 Database와 테이블 찾기

가령 아래와 같은 양식의 정보가 제공되었을 때, 수백개의 데이터베이스 안에서 사람이 일일이 하나씩 확인해보며 어떤 필드에 어떤 값이 들어가있는지 알려면 막막할 것이다

간단하지만 컴퓨터의 연산속도를 통하여 복호화된 DB 들을 불러와 SQLite 와 연동하여 DataTable 으로 만들고 loop 를 돌면서 어디 테이블에, 어디 칼럼에 위치하는지 확인해 보았다

		try
			{
				string _folderPath		= @"D:\xxxx\";
				string[] _files			= Directory.GetFiles(_folderPath, "*.DB");

				string _find = "198523000"; // 찾고자 하는 키워드 
				
				foreach (var _file in _files)
				{
					string _connectionString = string.Format(@"Data Source={0};Pooling=true;FailIfMissing=false;", _file);
					var _conn = new SQLiteConnection(_connectionString);
					_conn.Open();

					// getting valid tables from database;
					string stm = "SELECT name FROM sqlite_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%' UNION ALL SELECT name FROM sqlite_temp_master WHERE type IN ('table', 'view') ORDER BY 1;";
					var cmd = new SQLiteCommand(stm, _conn);
					cmd.ExecuteNonQuery();

					SQLiteDataReader sdr = cmd.ExecuteReader();

					// list of name in current database
					DataTable _names = new DataTable();
					_names.Load(sdr);
					sdr.Close();

                   
					for (int i = 0; i < _names.Rows.Count; i++)
					{
                        try
                        {
							//Debug.WriteLine("Now at " + _names.Rows[i]["name"]);
							stm = string.Format("SELECT * FROM {0}", _names.Rows[i]["name"]);
							cmd = new SQLiteCommand(stm, _conn);
							cmd.ExecuteNonQuery();
							sdr = cmd.ExecuteReader();

							DataTable _dt = new DataTable();
							_dt.Load(sdr);
							sdr.Close();

							if (_dt.Rows.Count > 0)
							{
								var ret = getMatchRow(_dt, _find);
								if (ret != null)
								{
									Debug.WriteLine("CURRENT TABLE		:   " + _names.Rows[i]["name"]);
									Debug.WriteLine("CURRENT DATABASE	:	" + _file);
									for (int j = 0; j < ret.ItemArray.Length; j++)
									{
										Debug.WriteLine(string.Format("COL : {0}			VALUE : {1}", ret.Table.Columns[j], ret.ItemArray[j]));
									}
								}
							}
						}
						catch (Exception e)
						{
							continue;
						}
					}
					_conn.Close();

				}
			}
  • 복호화된 DB 에서 SQLite 를 연동한다.

    ✔ sqlite 라는 이름의 다른 Nuget 패키지가 많을텐데 위 사진의 패키지로 다운받는다

  • DataSource 를 통해 연결하고자 하는 데이터베이스의 경로를 넣고 커넥션을 생성한다

  • conn.Open() 하여 연결을 열어주는 것을 잊지 말자

  • SELECT name FROM sqlite_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%' UNION ALL SELECT name FROM sqlite_temp_master WHERE type IN ('table', 'view') ORDER BY 1 쿼리는 데이터베이스 내의 모든 테이블 이름을 갖고 오는 쿼리이다

  • SQLiteCommand 를 통해 수행하고자 하는 쿼리, 커넥션을 넣고 SQLiteDataReader 를 통하여 결과값을 저장한다

  1. 각 데이터베이스의 테이블에서 SELECT * FROM {table_name} 하여 모든 col, row 의 값을 찾는다
  2. getMatchRow 메서드는 테이블값이 키워드 를 포함하면 해당 row 를 주도록 하는 메서드이다
public static DataRow getMatchRow(DataTable dt, string keyword)
        {
			for(int i=0; i<dt.Rows.Count; i++)
            {
				for(int j=0; j<dt.Columns.Count; j++)
                {
                    try
                    {
						if (dt.Rows[i].ItemArray[j].ToString().Contains(keyword))
						{
							return dt.Rows[i];
						}
					}
					catch(Exception er)
                    {
						Debug.WriteLine("error occured in getMatch Row");
                    }
					//Debug.WriteLine(dt.Rows[i].ItemArray[j].ToString());
                    
                }
            }
			return null;
        }
  1. 만약 일치하는 row 를 찾는다면 해당 테이블의 위치, 데이터베이스의 이름, 필드명을 Debug 를 통하여 확인한다

  • 수십개의 테이블이지만 몇차례 돌려본 결과 급여에 관계된 테이블들 정보를 추출할 수 있었다

0개의 댓글