java, c#등의 언어에서 jdbc, odp.net등 을 이용하여 DB에 연결한다.

해당 커넥터를 사용할때

PL/SQL, Pro*C에서 사용했던 exception중


아래 2개 

"ORA-01403 no data found", 

"ORA-01422 TOO_MANY_ROWS"

는 에러코드로 받지 못한다.


특정 자료형에 db에서 구한 값을 담으려고 할떄 나는 오류로 해당 에러를 catch 하고자 한다면 그 case에 맞는 로직을 구현하여 catch 하는게 맞겠다.

처리방안)

"ORA-01403 not data found" => null 체크, 결과값 count 

"ORA-01422 TOO_MANY_ROWS" => 리턴될 결과/받는 데이타의 type이 배열 형태인지 아닌지 확인하여 처리



참고1) https://ko.wikipedia.org/wiki/PL/SQL

PL/SQL(피엘에스큐엘) : 상용 관계형 데이터베이스 시스템인 오라클 DBMS에서 SQL 언어를 확장하기 위해 사용하는 컴퓨터 프로그래밍 언어 중 하나이다. 


특징 : 자료 내부에서 SQL 명령문만으로 처리하기에는 복잡한 자료의 저장이나 프로시저와 트리거 등을 작성하는 데 쓰인다. 

PL/SQL의 구조는 에이다 프로그래밍 언어를 본떠 만들어졌다고 알려졌다. 따라서 두 언어는 그 구조가 범용 언어인 파스칼의 구문과 비슷하다. 

범용 언어인 C와 C++ 그리고 파스칼 및 포트란 등의 프로그래밍 언어와는 다른 점으로 범용 언어들이 컴퓨터 시스템에서 특정한 작업을 처리하기 위해 만들어진 언어라고 볼 때 PL/SQL은 단지 오라클의 관계형 데이터베이스 (RDBMS)에서만 사용된다는 점이다.

PL/SQL 외에도 각 관계형 데이터베이스마다 확장 언어들이 있다. 이러한 확장 언어의 대표적인 예로 마이크로소프트의 마이크로소프트 SQL 서버와 SybaseASE에는 트랜잭트 SQL(Transact SQ; TSQL)이 있고 PostgreSQL에는 PL/pgSQL 마지막으로 IBM DB2는 ISO SQL의 SQL/PSM 표준을 따르는 SQL Procedural를 포함한다.


PL/SQL 프로그램 단위 : 

PL/SQL 익명 블록

함수

프로시저

패키지

패키지 사양

패키지 바디

트리거


참고2) https://www.ibm.com/support/knowledgecenter/ko/SSEPGG_10.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0002212.html

Pro*C에서 사용되는 SQLCA

SQLCA : 모든 SQL문의 실행 끝에 갱신되는 변수의 콜렉션입니다.


오류 보고:서버 오류 조건이 항상 보고됩니다. 서버 오류가 보고되면 SQLCA에 대한 추가는 없습니다.

심각한 오류가 발생하지 않는 경우 교착 상태 오류는 다른 오류보다 우선합니다.

다른 모든 오류의 경우, 첫 번째 음수 SQL 코드의 SQLCA가 리턴됩니다.

음수 SQL 코드가 감지되지 않는 경우, 첫 번째 경고(즉, 양수 SQL 코드)의 SQLCA가 리턴됩니다.

파티션된 데이터베이스 시스템에서, 데이터 처리 조작이 하나의 데이터베이스 파티션에서 비어 있지만 다른 데이터베이스 파티션에 데이터가 있는 테이블에 대해 호출되는 경우 이 규칙에 대한 예외가 발생합니다. 테이블이 모든 데이터베이스 파티션에서 비어 있거나 UPDATE문에서 WHERE절을 충족하는 행이 없기 때문에 모든 데이터베이스 파티션에서 에이전트가 SQL0100W를 리턴하는 경우 SQLCODE +100만이 애플리케이션에 리턴됩니다.


'DataBase > Oracle' 카테고리의 다른 글

select for update wait/nowait  (0) 2018.07.22
Oracle Error Code description  (0) 2018.04.20


C#에서 mariadb 사용하기

https://dev.mysql.com/downloads/connector/net/

Download Connector/NET(mysql-connector-net-8.0.13.msi)

mysql-connector-net-8.0.13.msi



 

C#프로젝트 [참조]에 라이브러리를 추가한다.(1개 : MySql.Data.dll)

C:\Program Files (x86)\MySQL\MySQL Connector Net 8.0.13\Assemblies\v4.5.2\MySql.Data.dll




<dbconnection class>에서 아래 라이브러리 이용하여 커넥션 클래스 구성.

오라클,msSql, mariadb 모두 비슷한 패턴임.

------------------------------------------------

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Data;

using MySql.Data.MySqlClient;


namespace testWebApplication1

{

    public class MariaDbAccess

    {


        #region 멤버변수


        private MySqlConnection oCnn = null;

        /// <summary>

        /// DB 연결 스트링

        /// </summary>

        private string _connectionString = "SERVER=서버;DATABASE=데이타베이스명;UID=아이디;PASSWORD=패스워드;";


------------------------------------------------


'프로그래밍 > c#' 카테고리의 다른 글

WebBrowser이용한 스크린스크래핑  (0) 2018.05.09
WebBrowser.DocumentText 한글깨짐  (0) 2018.05.07
using MySqlConnector  (0) 2018.05.07

스크린스크래핑

WebBrowser이용해서 website에 렌더링된 html의 특정값을 추출한다.

예를 들어 특정 사이트 모 카테고리에 있는 내용을 모두 가져와서 데이터화하고 그것을 분석하고 싶을 때 스크래핑을 사용하면 편리하다.

 

아래 code

 

특정 카테고리의의 글list를 통해 key, title을 추출하고

Key를 이용해 본문내용의 text를 가져와서 db화 한 내용이다.

글의 pattern등 분석자료로 사용할 목적으로 데이터가 필요하나 해당사이트에서 DB를공개하진 않으니 이렇게 스크랩핑해서 자료화해서 사용하는 것이다.

이렇게 하지 않으면 사이트의 모든 사이트 내용을 클릭~클릭~클릭~ 하겠지.

 

이렇게 프로그램하기 전에 사전에 해당 사이트를 분석하고 맞게 프로그래밍하면 된다.


step1) 카테고리의의 글list를 통해 key, title을 추출 : webSiteContentsList();

 => 추출된 data를 수작업으로 insert스크립트만들어 TMP_HELP 에 insert함.

step2) Key를 이용해 본문내용의 text를 가져와서 db화 한 내용 : webSiteContentsDetail(oBrowser);


<c# code>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using MySql.Data.MySqlClient;

namespace ScrappingWinForms
{
public partial class Form1 : Form
{

int iq = 0;
string contentsKey = "";

string sConnectionString = "Server=localhost;contentsKey=root;Pwd=???;Database=??????";
string sContentsUrl = "http://www.doitforyou.co.kr/sread.html?key="; //fake url임
string sListUrl = "http://www.doitforyou.co.kr/sub.html?&sec=cc&section=culture&page="; //fake url임

String Url = string.Empty;

public Form1()
{
InitializeComponent();

//WebBrowser로 사이트 로딩시 자바스크립트 바인딩안되어 에러나는 경우.
//자바스크립트 오류(dialogbox) 무시하고 진행가능하도록 제어함.
this.webBrowserViewer.ScriptErrorsSuppressed = true;
webBrowserViewer.DocumentTitleChanged += new EventHandler(webBrowserViewer_DocumentTitleChanged);
}
private void btnSearch_Click(object sender, EventArgs e)
{
// surftheWeb();
if (iq < 200)
{
selectContentsKeyfromWebsite();
}
}

#region surftheWeb :WebBrowser에 SitePage 브라우징한다.
private void surftheWeb()
{
Url = txtUrl.Text;
webBrowserViewer.Navigate(Url);
}

private void surftheWeb(String sUrl)
{
webBrowserViewer.Navigate(sUrl);
}

#endregion


#region Select / Update from the WebSite

private void selectContentsKeyfromWebsite()
{
MySqlConnection oConnection = new MySqlConnection(sConnectionString);
oConnection.Open();

try
{
MySqlCommand cmd = oConnection.CreateCommand();
cmd.CommandText = "SELECT HELP_TOPIC_ID FROM TMP_HELP WHERE HELP_TOPIC_ID >= 100 AND DESCRIPTION = '' LIMIT 1";
MySqlDataAdapter aDap = new MySqlDataAdapter(cmd);
DataSet dsData = new DataSet();
aDap.Fill(dsData);
if (contentsKey != dsData.Tables[0].Rows[0][0].ToString())
{
contentsKey = dsData.Tables[0].Rows[0][0].ToString();
String sUrl = String.Empty;
sUrl = sContentsUrl + contentsKey;
surftheWeb(sUrl);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (oConnection.State == ConnectionState.Open)
{
oConnection.Close();
}
}
}
/// <summary>
/// key값으로 contents내용을 업데이트 한다.
/// </summary>
/// <param name="sHelp_topic_id"></param>
/// <param name="sDescription"></param>
private void updateContentonIldaro(String sHelp_topic_id, String sDescription)
{
MySqlConnection oConnection = new MySqlConnection(sConnectionString);
oConnection.Open();

try
{
MySqlCommand cmd = oConnection.CreateCommand();
cmd.CommandText = "UPDATE tmp_help set description = @description where help_topic_id = @help_topic_id";
cmd.Parameters.AddWithValue("@help_topic_id", int.Parse(sHelp_topic_id));
cmd.Parameters.AddWithValue("@description", sDescription);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (oConnection.State == ConnectionState.Open)
{
oConnection.Close();

//key를 다시 조회한다.
btnSearch_Click(null, null);
}
}
}
#endregion

/// <summary>
/// WebBrowser's DocumentCompleted Event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void webBrowserViewer_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser oBrowser = sender as WebBrowser;
//txtSource.Text = StreamConvertEUCKRtoUTF8(oBrowser);

this.txtUrl.Text = oBrowser.Url.AbsoluteUri;

//webSiteContentsList();
webSiteContentsDetail(oBrowser);
}

private void webSiteContentsDetail(WebBrowser oBrowser)
{
iq++; //반복수행위한 카운팅
getWebSiteContentsDetail(oBrowser);
}

/// <summary>
/// 게시판 글list, Paging있음
/// </summary>
private void webSiteContentsList() {

iq++; //paging 숫자

getData();

if (iq < 21)
{
String sUrl = sListUrl + iq.ToString();
surftheWeb(sUrl);
}
}

/// <summary>
/// 1.WebBrowser로 rendering된 html을 TagName으로 HtmlElementCollection에 담는다.
/// 2.HtmlElementCollection => HtmlElement에 담긴 InnerHtml분석한다.
/// 3.HtmlElement[]에 추출하려는 대상을 담는다.
/// </summary>
/// <param name="wb"></param>
/// <param name="tagName"></param>
/// <returns></returns>
private HtmlElement[] GetElementsByTagName(WebBrowser wb, string tagName)
{
var l = new List<HtmlElement>();

var els = wb.Document.GetElementsByTagName(tagName); // all elems with tag
foreach (HtmlElement el in els)
{
if (el.InnerHtml == null)
{
continue;
}

if(el.InnerHtml.StartsWith("<A href=\"read.html"))
{
l.Add(el);
}
}

return l.ToArray();
}


/// <summary>
/// 1.WebBrowser로 rendering된 html을 TagName으로 HtmlElementCollection에 담는다.
/// 2.HtmlElementCollection => HtmlElement에 담긴 요소들중 className을 이용해서 추출하려는 대상을 뽑는다..
/// 3.HtmlElement[]에 추출하려는 대상을 담는다.
/// </summary>
/// <param name="wb"></param>
/// <param name="tagName"></param>
/// <param name="className"></param>
/// <returns></returns>
private HtmlElement[] GetElementsByTagNClassName(WebBrowser wb, string tagName, string className)
{
var l = new List<HtmlElement>();

var els = wb.Document.GetElementsByTagName(tagName); // all elems with tag
foreach (HtmlElement el in els)
{

if (el.GetAttribute("className") == className)
{
l.Add(el);
}
}

return l.ToArray();
}

/// <summary>
/// 글 상세 페이지에서 추출하고자 하는 Text만 가져온다.
/// </summary>
/// <param name="oBrowser"></param>
private void getWebSiteContentsDetail(WebBrowser oBrowser)
{
var arrCollection = GetElementsByTagNClassName(webBrowserViewer, "td", "contentsbody");
for (int i = 0; i < arrCollection.Length; i++)
{
//Console.WriteLine(arrCollection[i].InnerHtml);

String sText = String.Empty;
//sText = arrCollection[i].InnerHtml;
sText = arrCollection[i].OuterText;

if (sText == null)
{
//글 text가 없는 경우가 있음
//case1) 이미지로 대체한 경우 img html tag가 글 대신 있음
sText = arrCollection[i].InnerHtml;
}
if (contentsKey.Equals(oBrowser.Url.AbsoluteUri.Replace(sContentsUrl, "")))
{
updateContentonIldaro(contentsKey, sText);
}
}
}

private void getData() {

// getting day and night temperature
var arrCollection = GetElementsByTagName(webBrowserViewer, "dt");

DataTable dt = new DataTable();

dt.Columns.Add("contentsKey", typeof(int));
dt.Columns.Add("Title", typeof(string));

Console.WriteLine("-- " + iq.ToString() + " --------------");
txtSource.Text = txtSource.Text + "-- " + iq.ToString() + " --------------" + "\r\n";

for (int i = 0; i < arrCollection.Length; i++) {
//Console.WriteLine(arrCollection[i].InnerHtml);

String sText = String.Empty;
sText = arrCollection[i].InnerHtml;
sText = sText.Replace("<A href=\"sread.html?key=", "").Replace("</A>", "").Replace("\"", "");

String[] arrSplit = sText.Split('>');

dt.Rows.Add(arrSplit[0],arrSplit[1]);

Console.WriteLine(arrSplit[0] + ":" + arrSplit[1]);

txtSource.Text = txtSource.Text + arrSplit[0] + ":" + arrSplit[1] + "\r\n";

}

}

#endregion


reference to :  https://www.codeproject.com/Tips/858775/Csharp-Website-HTML-Content-Parsing-or-How-To-Get


'프로그래밍 > c#' 카테고리의 다른 글

c#에서 mariadb사용하기  (0) 2018.11.10
WebBrowser.DocumentText 한글깨짐  (0) 2018.05.07
using MySqlConnector  (0) 2018.05.07

WebBrowser 객체를 이용해서 web페이지를 볼 때 DocumentText 메소드로 렌더링된 html을 읽어올 때 default utf-8 encoding type이라 이상태에서는 euc-kr의 한글은 깨진다

이 경우 스트림리더를 사용해서 실제 페이지의 encoding type으로 읽어들이면 된다.

 

샘플) WebBrowser.DocumentText 로 소스를 봤을경우.

 

<html>

<head>

<title><��̴ϽƮ ���� �ϴ�></title>

<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" />

 

 

StreamReader를 이용해 페이지의 encoding type으로 읽어들인경우

 

<html>

<head>

<title><오늘은 어린이날 입니다></title>

 

<<C# Code>>

 

/// <summary>

        /// WebBrowser's DocumentCompleted Event

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void webBrowserViewer_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)

        {

            // ((WebBrowser)sender).Document.Window.Error +=   new HtmlElementErrorEventHandler(Window_Error);

 

            WebBrowser oBrowser = sender as WebBrowser;

 

            txtSource.Text = StreamConvertEUCKRtoUTF8(oBrowser);

                       

        }

 

        /// <summary>

        /// Using WebBrowser web page

        /// 웹페이지 Encoding type EUC-KR 이면 WebBrowser.DocumentText html 렌더링된 text 볼때 한글이 깨진다.

        /// 아래처럼 스트림리더로 EUC-KR type으로 읽어온다.

        /// </summary>

        /// <param name="oBrowser"></param>

        /// <returns></returns>

        private String StreamConvertEUCKRtoUTF8(WebBrowser oBrowser)

        {

            String sResult = String.Empty;

 

            Stream oStream;

            StreamReader oStreamReader;

            oStream = oBrowser.DocumentStream;

            oStreamReader = new StreamReader(oStream, System.Text.Encoding.GetEncoding(oBrowser.Document.Encoding));

            oStream.Position = 0;

            sResult = oStreamReader.ReadToEnd();

 

            return sResult;

        }


'프로그래밍 > c#' 카테고리의 다른 글

c#에서 mariadb사용하기  (0) 2018.11.10
WebBrowser이용한 스크린스크래핑  (0) 2018.05.09
using MySqlConnector  (0) 2018.05.07


c#에서 Mariadb를 연결할때 MySqlConnector를 사용한다.

VS에서 NgGet을 이용해서 쉽게 검색하고 설치할 수 있다. 

*NgGet 이놈 참 좋다~


MySqlConnector는 MIT 라이센스 그냥 사용하면 된다.





connector설치한김에 테스트까지 해봐야지요



c#코드


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.IO;

using MySql.Data.MySqlClient;


namespace ScrappingWinForms

{

    public partial class Form1 : Form

    {

        string sConnectionString = "Server=localhost;Uid=root;Pwd=???????;Database=???";


        String Url = string.Empty;


        public Form1()

        {

            InitializeComponent();


            //WebBrowser로 사이트 로딩시 자바스크립트 바인딩안되어 에러나는 경우.

            //자바스크립트 오류(dialogbox) 무시하고 진행가능하도록 제어함. 

            this.webBrowserViewer.ScriptErrorsSuppressed = true;

            webBrowserViewer.DocumentTitleChanged += new EventHandler(webBrowserViewer_DocumentTitleChanged);

        }


        private void btnSearch_Click(object sender, EventArgs e)

        {

            surftheWeb();

        }

        

        private void surftheWeb()

        {

            Url = txtUrl.Text;

            webBrowserViewer.Navigate(Url);

        }


        /// <summary>

        /// WebBrowser's DocumentCompleted Event

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void webBrowserViewer_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)

        {

            // ((WebBrowser)sender).Document.Window.Error +=   new HtmlElementErrorEventHandler(Window_Error);


            WebBrowser oBrowser = sender as WebBrowser;


            txtSource.Text = StreamConvertEUCKRtoUTF8(oBrowser);

                        

        }


        /// <summary>

        /// Using WebBrowser web page 

        /// 웹페이지 Encoding type 이 EUC-KR 이면 WebBrowser.DocumentText로 html로 렌더링된 text를 볼때 한글이 깨진다.

        /// 아래처럼 스트림리더로 페이지 EUC-KR type을 읽어들인다.

        /// </summary>

        /// <param name="oBrowser"></param>

        /// <returns></returns>

        private String StreamConvertEUCKRtoUTF8(WebBrowser oBrowser)

        {

            String sResult = String.Empty;


            Stream oStream;

            StreamReader oStreamReader;

            oStream = oBrowser.DocumentStream;

            oStreamReader = new StreamReader(oStream, System.Text.Encoding.GetEncoding(oBrowser.Document.Encoding));

            oStream.Position = 0;

            sResult = oStreamReader.ReadToEnd();


            return sResult;

        }

         

        private void webBrowserViewer_DocumentTitleChanged(object sender, EventArgs e)

        {

            //this.Text = webBrowser1.DocumentTitle.ToString();


            this.groupBox1.Text = webBrowserViewer.DocumentTitle;

        }



        private void loadTestData() {

            MySqlConnection oConnection = new MySqlConnection(sConnectionString);

            oConnection.Open();


            try

            {

                MySqlCommand cmd = oConnection.CreateCommand();

                cmd.CommandText = "SELECT * FROM TMP_help order by help_topic_id desc";

                MySqlDataAdapter aDap = new MySqlDataAdapter(cmd);

                DataSet dsData = new DataSet();

                aDap.Fill(dsData);


                dgViewSample.DataSource = dsData.Tables[0].DefaultView;


            }

            catch (Exception ex)

            {

                throw ex;

            }

            finally {

                if (oConnection.State == ConnectionState.Open)

                {

                    oConnection.Close();

                }

            }

        }

      


        private void btnForTest_Click(object sender, EventArgs e)

        {

            loadTestData();

        }

     

    }

}



'프로그래밍 > c#' 카테고리의 다른 글

c#에서 mariadb사용하기  (0) 2018.11.10
WebBrowser이용한 스크린스크래핑  (0) 2018.05.09
WebBrowser.DocumentText 한글깨짐  (0) 2018.05.07

+ Recent posts