천객만래 [千客萬來] (It has an interminable succession of visitors)


MySQL 5 C# sample code using ObjectDataSources



Introduction

I created this example because I could not find a simple explanation for using MySQL 5 with ObjectDataSources in ASP.NET 2.0.

Let me say, I am really impressed with MySQL. I was able to install it easily on my Windows XP machine and get it running in about an hour. I am a long time MS SQL user, and was very frustrated with trying to use Oracle and Firebird. I realize, the problem is that I am spoiled from MS SQL Server, but hey I''m busy and I like easy to use tools :)

If you''re getting started with MySQL and ASP.NET, then I recommend these steps:

  1. Go to the MySQL website, download and install “Current Release (recommended).
  2. Download and install: MySQL Administrator (to administer your MySQL server, the first download just installs only the server).
  3. Download and install: Connector/Net 1.0 (you need this to get your ASP.NET pages to talk to your MySQL server).
  4. You can also download: MySQL Query Browser – (a graphical client to work with your MySQL databases and run queries).
  5. Read and follow this guide: A Step-by-Step Guide to Using MySQL with ASP.NET.

Using the code

To install the code:

  1. You must have MySQL 5 up and running.
  2. Install MySQL Connector/Net 1.0.
  3. Create a MySQL 5 database named Test.
  4. Create a table in that database called Message:
    CREATE TABLE test.message (
    
        Entry_ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        Name VARCHAR(45),
        Email VARCHAR(45),
        Message VARCHAR(200),
        PRIMARY KEY (Entry_ID)
        )
        AUTO_INCREMENT=32
        CHARACTER SET latin1 COLLATE latin1_swedish_ci;
  5. Create these four MySQL stored procedures in the Test database:
    PROCEDURE `test`.`DeleteMessage`(IN param1 INT)
    BEGIN
    Delete From test.message
    WHERE Entry_ID = param1;
    END
    PROCEDURE `test`.`InsertMessage`(IN param1 VARCHAR(50), IN param2 
        VARCHAR(50), IN param3 VARCHAR(200))
    BEGIN
    INSERT INTO message(Name, Email, Message)
    VALUES(param1,param2,param3);
    END
    PROCEDURE `test`.`ShowAll`()
    BEGIN
    SELECT 
      message.Entry_ID,
      message.Name, 
      message.Email, 
      message.Message
    FROM
      test.message;
    END
    PROCEDURE `test`.`UpdateMessage`(IN paramkey INT, IN param1 VARCHAR(50), 
        IN param2 VARCHAR(50), IN param3 VARCHAR(200))
    BEGIN
    UPDATE    message
    SET              Name = param1, Email = param2, Message = param3
    WHERE     (message.Entry_ID = paramkey);
    END
  6. Unzip "MySQL" and configure IIS to point to it. Make sure you configure the web server to use ASP.NET 2.0.
  7. Open "web.config" and change the line:
    <add name="MySQLConnectionString" connectionString="server=localhost; 
       user id=myuser; password=mypass; database=test; pooling=false;" 
       providerName="MySql.Data.MySqlClient"/>

    to connect to your MySQL database.

  8. Browse to the default.aspx page through IIS.

This is the class that uses Generics to supply the data that is consumed by the ObjectDataSource control:

using System;
using System.Collections.Generic;
using System.Data;
using MySql.Data.MySqlClient;
using System.Configuration;
using System.ComponentModel;

[DataObject(true)]
public static class MessagesDB
{
    private static string GetConnectionString()
    {
        return ConfigurationManager.ConnectionStrings
        ["MySQLConnectionString"].ConnectionString;
    }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public static List<MessageItem> GetMessages()
    {
        MySqlCommand cmd = new MySqlCommand("ShowAll", 
                           new MySqlConnection(GetConnectionString()));
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Connection.Open();
        MySqlDataReader dr = 
           cmd.ExecuteReader(CommandBehavior.CloseConnection);

        List<MessageItem> MessageItemlist = new List<MessageItem>();
        while (dr.Read())
        {
            MessageItem MessageItem = new MessageItem();
            MessageItem.Entry_ID = Convert.ToInt32(dr["Entry_ID"]);
            MessageItem.Message = Convert.ToString(dr["Message"]);
            MessageItem.Name = Convert.ToString(dr["Name"]);
            MessageItem.Email = Convert.ToString(dr["Email"]);
            MessageItemlist.Add(MessageItem);
        }
        dr.Close();
        return MessageItemlist;
    }

    [DataObjectMethod(DataObjectMethodType.Insert)]
    public static void InsertMessage(MessageItem MessageItem)
    {
        MySqlCommand cmd = new MySqlCommand("InsertMessage", 
                           new MySqlConnection(GetConnectionString()));
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new MySqlParameter("param1", MessageItem.Name));
        cmd.Parameters.Add(new MySqlParameter("param2", MessageItem.Email));
        cmd.Parameters.Add(new MySqlParameter("param3", MessageItem.Message));
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
        cmd.Connection.Close();
    }

    [DataObjectMethod(DataObjectMethodType.Update)]
    public static int UpdateMessage(MessageItem MessageItem)
    {
        MySqlCommand cmd = new MySqlCommand("UpdateMessage", 
                           new MySqlConnection(GetConnectionString()));
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new MySqlParameter("paramkey", MessageItem.Entry_ID));
        cmd.Parameters.Add(new MySqlParameter("param1", MessageItem.Name));
        cmd.Parameters.Add(new MySqlParameter("param2", MessageItem.Email));
        cmd.Parameters.Add(new MySqlParameter("param3", MessageItem.Message));
        cmd.Connection.Open();
        int i = cmd.ExecuteNonQuery();
        cmd.Connection.Close();
        return i;
    }

    [DataObjectMethod(DataObjectMethodType.Delete)]
    public static int DeleteMessage(MessageItem MessageItem)
    {
        MySqlCommand cmd = new MySqlCommand("DeleteMessage", 
                new MySqlConnection(GetConnectionString()));
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new MySqlParameter("param1", MessageItem.Entry_ID));
        cmd.Connection.Open();
        int i = cmd.ExecuteNonQuery();
        cmd.Connection.Close();
        return i;
    }

The class above uses the class "MessageItem" to pass the parameters to and from the ObjectDataSource control:

using System;

public class MessageItem
{
    int _Entry_ID;
    string _Message;
    string _Name;
    string _Email;

    public MessageItem()
    {
    }

    public int Entry_ID
    {
        get
        {
        return _Entry_ID;
        }
        set
        {
        _Entry_ID = value;
        }
    }

    public string Message
    {
        get
        {
            return _Message;
        }
        set
        {
            _Message = value;
        }
    }

    public string Name
    {
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
        }
    }

    public string Email
    {
        get
        {
            return _Email;
        }
        set
        {
            _Email = value;
        }
    }
}

This is the .aspx file that contains the ObjectDataSource control as well as a GridView for editing data and a DetailsView for inserting a record:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
   TypeName="MessagesDB" OldValuesParameterFormatString="original_{0}" 
   SelectMethod="GetMessages" DataObjectTypeName="MessageItem" 
   DeleteMethod="DeleteMessage" InsertMethod="InsertMessage" 
   UpdateMethod="UpdateMessage">
</asp:ObjectDataSource>
<br />
<asp:GridView ID="GridView1" runat="server" 
      AutoGenerateColumns="False" 
      DataSourceID="ObjectDataSource1" 
      DataKeyNames="Entry_ID">
 <Columns>
   <asp:BoundField DataField="Entry_ID" HeaderText="Entry_ID" 
           SortExpression="Entry_ID" Visible="False" />
   <asp:CommandField ShowEditButton="True" />
   <asp:CommandField ShowDeleteButton="True" />
   <asp:BoundField DataField="Name" 
         HeaderText="Name" SortExpression="Name" />
   <asp:BoundField DataField="Email" 
         HeaderText="Email" SortExpression="Email" />
   <asp:BoundField DataField="Message" 
         HeaderText="Message" SortExpression="Message" />
 </Columns>
</asp:GridView>
<br />
<strong><span style="text-decoration: underline">
      Insert New Record:</span></strong><br />

<asp:DetailsView ID="DetailsView1" runat="server" 
    AutoGenerateRows="False" BorderStyle="None"
    CellSpacing="5" DataSourceID="ObjectDataSource1" 
    DefaultMode="Insert" GridLines="None"
    Height="50px" Width="300px">
  <Fields>
    <asp:BoundField DataField="Name" HeaderText="Name" />
    <asp:BoundField DataField="Email" HeaderText="Email" />
    <asp:BoundField DataField="Message" HeaderText="Message" />
    <asp:CommandField ButtonType="Button" 
         ShowInsertButton="True" ShowCancelButton="False" />
  </Fields>
</asp:DetailsView>

Note

The assembly "MySql.Data.dll" is in the "/bin" directory so the "MySql.Data.MySqlClient" will work.

I hope this helps!



MySQL_CS_samplesource.zip



Posted by SB패밀리

MySQL   패스워드 날렸을 때 처리


1. mysql  프로세스를 죽입니다.
# ps -aux | grep mysql

2.DB를 싱글모드로 실행하세요.
# ./mysql/bin/mysqld_safe --user=mysql --skip-grant-tables &

3. root 패스워드를 변경하세요.
[기본 디렉토리에 설치 하였다고 가정합니다.]

# cd /usr/local/mysql/bin
# mysql

mysql> use mysql;
mysql> update user set password=password('새로운암호입력') where user='root';
mysql> flush privileges;
mysql>q

4.다시 시작합니다.
# ./mysqladmin -u root -p shutdown
# ./bin/mysqld_safe &

여기까지 하시면 됩니다.

Posted by SB패밀리

SQL EDITOR상에서의 편리한 단축키 

ESC: 열린 윈도우 닫기 
F1: 모든 단축키를 보여준다. 
F2: FULL SCREEN 
F4: Table, View, Proc, Funct, Package를 DESC(테이블명에 커서를 둔 상태에서 해야함) 
F6: SQL Editor와 결과창간의 전환 
F7: 화면을 모두 CLEAR 
F8: 실행했던 SQL들의 HISTORY 
F9: 모든 쿼리 실행(Ctrl+Enter는 현재 쿼리만 실행) 
Ctrl+F9: 실제 쿼리를 실행하지 않고 validate함 
Ctrl+. : table Completion (매칭되는 테이블목록 출력) 
Ctrl+T : Columns Dropdown (해당테이블의 컬럼목록 표시) 
Alt+Up : History Up (리눅스 bash의 UP키와 같다.) 
Alt+Down: History Down (리눅스 bash의 DOWN키와 같다.) 
Ctrl+Tab: MDI Child윈도간 전환 

그냥 'desc 테이블명' 을 치면, 팝업윈도로 해당 테이블의 컬럼목록윈도가 표시된다. 
이때, 해당 컬럼을 double-click하면 SQL Editor로 반영된다. 

"테이블명."까지 입력하고 좀 있으면, 해당 테이블의 컬럼목록이 표시된다. 
마치 프로그래밍툴에서 클래스내 멤버들의 목록을 표시하듯이.. 
Ctrl+T는 출력된 목록을 취소했을 경우, 다시 불러낼때 쓰인다. 

test, member 2개의 테이블이 있다고 하자. 
select * from t까지 입력하고 Ctrl+.를 치면 select * from test로 테이블명을 완성시켜준다. 
system계정에서는 안되더군.. 일반계정만 가능했다. 

SQL문을 실행시 

Ctrl+Enter 
현재 커서의 SQL문 실행 
여러개의 SQL문이 있을때, SQL문들을 개행문자로 분리해주면 된다. 
해당 커서에서 개행문자가 있는 곳까지만 하나의 SQL문으로 간주한다. 

F9 
SQL Editor의 SQL문 실행하여 Grid에 출력. 
여러 SQL문들을 개행문자로 구분하지 않는다는 것을 제외하면, 위의 Ctrl+Enter와 동일하다. 
에디터내의 모든 SQL문은 하나로 취급하므로, 여러 개의 SQL문이 있으면 실행할 SQL문만 Selection하여 실행(F9)해준다. 

F5 
SQL Editor내의 모든 SQL문 실행. 여러개의 SQL문들을 모두 실행하여 SQL*PLUS와 같이 출력해준다. 
이것은 출력이 Grid로 표시되지 않고 Editor윈도에 표시되므로, SQL*PLUS의 출력과 같이, 
다른 편집기로의 복사/붙여넣기 할때 사용하면 유용하다.

Posted by SB패밀리

출처: http://dev.mysql.com/get/Downloads/Manual/manual-split.zip/from/http://mysql.holywar.net/

mySQL 영문 메뉴얼

http://dev.mysql.com/doc/ 에서 가져온 메뉴얼 파일 링크
나중에 간단히 command 라인 명령어도 정리하면 좋겠다.

MaxDB
maillist
3rd party MySQL
mySQL++ API
MySQL Connector/ODBC (MyODBC) 
MySQL Connector/J (java/jsp용)
example

등 여러가지가 있다.


http://dev.mysql.com/get/Downloads/Manual/manual-split.zip/from/ftp://mysql.byungsoo.net/pub/mysql/

Posted by SB패밀리

초보자를 위한 mysql sql 사용법  

글쓴이 : 오렌지블루
  저작권자 이메일 : haremoon@won.hongik.ac.kr

출처 : http://www.devshed.com/Server_Side/MySQL/Intro/
  작성일 : 2002/04/24 13:37:34



글내용

   
초보자를 위한 mysql 사용법 


출처를 확인할 길이 없습니다. 
다운 받는 자료인데 보기 편하게 쭈악 ~~~~ 
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 
원본사이트: http://www.devshed.com/Server_Side/MySQL/Intro/ 
* Beginning MySQL Tutorial 
*(o) By W.J. Gilmore 
*(o)| April 03, 1999 
(o)| | 번역 : 원주희(haremoon@won.hongik.ac.kr) 
| | | 번역일자 : 1999년 9월26일 
============================================================================== 

The Database 

데이타베이스는 이제 모든 사람들의 생활에서 없어서는 안될 매우 중요한 부분이 되어졌다. 
데이타베이스가 없다면 우리가 하고 있는 많은 일들은 매우 지루하고, 불편한 일들이 될 
것이다. 은행과 대학, 도서관은 이러한 데이타베이스 시스템에 크게 의존하고 있는 기관의 
예이며, 인터넷의 서치엔진, 온라인 쇼핑몰또한 데이타베이스를 이용하여 구축되어지고 있다. 
데이타베이스는 하나의 컴퓨터가 데이타베이스 서버와 개방적인 상호 관계를 할 수 있도록 
도와주는 도구이자 인터페이스의 역할을 한다. 

T.c.X. DataKonsultAB에 의해 개발된 MySQL 서버는 현재 시장에서 급속하게 성장하고 있는 
SQL(Structured Query Language) 데이타베이스 서버 중의 하나이다. MySQL은 
http://www.mysql.com에서 다운로드 받을 수 있으며, 다른 데이타베이스 서버에서는 보기 
드문 배열된 옵션과 유용한 특성을 가진 데이타베이스 프로그램을 제공한다. 무엇보다 
도 MySQL의 가장 큰 장점은 개인적으로나 상업적으로 그것을 이용하기 바라는 모든 사람들 
에게 무료로 제공되는 공개용 데이타베이스라는 것이다. MySQL을 사용하여 명확한 어플 
리케이션을 개발하고 싶다면 MySQL's licensing ection(http://www.mysql.com/Manual 
_chapter/manual_Licensing_and_Support.html)을 참고하기 바란다. 


MySQL 서버는 다음의 내용을 포함하여 헤아릴 수 없이 많은 능력 가지고 있다. 

· 동시 사용자의 수가 무제한적인 처리 능력 
· 50,000,000+ record를 처리할 수 있는 용량 
· 매우 빠른 명령 수행 능력(아마 시장에 나온 데이타베이스 중에 가장 빠를지도 모른다) 
· 쉽고 능률적인 사용자 특권 시스템 

그러나 어쩌면 그 수많은 능력 중에서도 가장 흥미로운 사실은 그것이 무료라는 것이다. 
T.c.X 는 일반 대중에게 공개용 데이타베이스인 MySQL을 무료로 제공하고 있다. 


누가 MySQL 서버를 사용하는가?(So Who's Using MySQL?) 

MySQL 데이타베이스 서버는 다음과 같은 기관들에서 막대한 대중성을 얻어가며 사용되어지 
고 있다. 
· Silicon Graphics (http://www.sgi.com
· Siemens (http://www.siemens.com
만약 위의 글이 설득력 있기에 충분하지 않다면 더 많은 MySQL 사용자 목록을 
MySQL User's List (http://www.mysql.com/users.html)에서 찾아 보기 바란다. 

이 글은 MySQL 서버의 필수 조작과 기본적인 명령을 수행하기 위한 서버의 셋업, 적절하게 
연결하는 방법을 포함하여 MySQL 서버의 기본적인 운용을 배우는 것을 도울 것이다. 
만약 이미 MySQL에 대해서 기본적인 이해를 하고 있다면 이장을 뛰어 넘고 다음 장으로 
가도 상관없다. 그러나 이 글에 쓰여진 명령어들은 좀 더 수준 높은 명령어를 위 
한 기초로서, MySQL 언어에 있는 가장 중요한 명령어 중의 하나라는 점을 기억하기 바란다. 


● Part 1: 미리살펴보기(At First Glance) 
======================================= 

MySQL은 일반적으로 telnet을 통해 들어간다. (괜찮은 Telnet 프로그램인 Easyterm은 
http://www.arachnoid.com에서 구할 수 있다.) 한번이라도 웹서버에 telnet으로 접속한 
적이 있다면 MySQL 서버에 접근하는 두 번째 명령어를 준비하기 바란다. 

연결하기 위한 절차는 다음과 같습니다. 

1. telnet 접속하기 : ISP에서 제공된 username(ID)과 password가 필요하다. 
-------------------------------------------------------------------------- 
login: haremoon 
Password: ******** 
Last login: Sat May 22 12:52:01 from 203.249.84.223 

Sun Microsystems Inc. SunOS 5.6 Generic August 1997 

You have new mail. 
[haremoon@won /user/center/haremoon]# 
-------------------------------------------------------------------------- 

2. MySQL 연결하기 - MySQL 사용을 위해서는 명확하게 주어진 username과 password가 필요 
하다. 이 정보는 ISP제공자에게 요청하면 제공된다. 

-------------------------------------------------------------------------- 
[haremoon@won /user/center/haremoon]# mysql -u root -p mysql 
-------------------------------------------------------------------------- 
Syntax : mysql -h hostname -u username -p password database 
실행파일 | 호스트 | db유저 | 패스워드 |사용할 데이타베이스이름 
또는 

mysql -h hostname -u username -password=password database 

-p 옵션에 의해 패스워드를 입력하는 프롬프트가 나오면 패스워드를 입력한다. 
Enter password: 

만약 MySQL이 올바르게 설치되었고 실행되었다면 다음과 같은 화면을 볼 수 있을 것이다. 
-------------------------------------------------------------------------- 
Welcome to the MySQL monitor. Commands end with ; or g. 
Your MySQL connection id is 267 to server version: 3.22.16a-gamma 
Type 'help' for help. 

mysql> 
-------------------------------------------------------------------------- 

데이타베이스에 이미 연결되어 있다면 MySQL 언어의 여러 가지 명령어를 실행시켜도 좋다. 
그러나 그렇지 않으면 먼저 데이타베이스에 연결하기 위해 다음의 명령을 수행합니다. 

-------------------------------------------------------------------------- 
mysql> use study --> 사용할 데이타베이스 
Reading table information for completion of table and column names 
You can turn off this feature to get a quicker startup with -A 

Database changed 
mysql> 
-------------------------------------------------------------------------- 
여러분은 지금 데이타베이스에 연결 되어있다. 한가지 주목할 점은 MySQL에서 대부분의 모든 
명령어는 세미클론 (;)에 의해 수행된다는 것이다. 

우선 커맨드 라인에서 help, h 또는 ? 라고 입력하면 간단한 명령어 도움말을 볼 수 있다. 

-------------------------------------------------------------------------- 
mysql> help 

MySQL commands: 
help (h) Display this text 
? (h) Synonym for `help' 
clear (c) Clear command 
connect (r) Reconnect to the server. Optional arguments are db and host 
edit (e) Edit command with $EDITOR 
exit () Exit mysql. Same as quit 
go (g) Send command to mysql server 
ego (G) Send command to mysql server; Display result verically 
print (p) print current command 
quit (q) Quit mysql 
rehash (#) Rebuild completion hash 
status (s) Get status information from the server 
use (u) Use another database. Takes database name as argument 

Connection id: 268 (Can be used with mysqladmin kill) 
mysql> 
-------------------------------------------------------------------------- 
이 명령들은 지금 당장 필요 없을지도 모른다. 그러나 그 명령어들의 의미를 정확히 
알기 위해서 한번씩 테스트해 보는 것이 좋을 것이다. status, use, print, connect, 
clear, 그리고 quit와 같은 명령어들은 매우 유용하게 사용될 것이다. 

여러분은 지금 서버에 연결해서 데이타베이스를 선택하고 기본적인 명령어를 수행하는 방법 
에 대해 기본적으로 이해해야 한다. 다음 장에서는 데이타베이스를 조작하기 위해 필요한 
개념과 기술을 다룰 것이다. 



● Part 2: 데이타베이스와 테이블(Datatypes and Tables) 
==================================================== 

데이타베이스는 좀 더 복잡한 데이타 구조의 계층에 지나지 않는다. MySQL에서는 정보의 
묶음(또는 레코드)을 테이블이라 부른다. 

이러한 레코드들은 데이타 타입이라고 알려진, 사용자에 의해 조작될 수 있는 아주 작은 크 
기의 개체들로 구성된다. 이러한 데이타타입들은 하나 또는 그 이상이 모여 레코드를 구 
성하며, 데이타베이스의 부분을 이루는 테이블은 레코드의 집합으로 구성된다. 우리는 다 
음과 같이 데이타베이스의 계층을 생각 할 수 있다. 

------------------------------------ 
Database < Table < Record < Datatype 
------------------------------------ 

데이타 타입은 사용자가 어떠한 프로젝트를 수행하기 위해 가장 적합한 테이블을 만들 
때 여러 가지의 형식과 크기로 나타낼 수 있다. 적절한 데이타 타입을 선택하고 결정하 
는 것은 데이타베이스의 실행에 큰 영향을 주므로 이 개념에 대해 자세히 이해해야 한다. 


2.1 MySQL 데이타 타입 


MySQL은 경험이 없는 사용자라 할 지라도 한번씩은 많은 종류의 데이타 타입들을 접해 
본 적이 있을 것이며, 또 쉽게 사용할 수 있다. 가장 일반적으로 사용되는 데이타 타입 
은 다음과 같다. 

⊙ CHAR (M) 

CHAR 데이타 타입은 고정된 길이의 문자열을 나타내는데 사용된다. 
하나의 CHAR 문자열은 1-255 자 범위의 문자를 저장할 수 있다. 

------------------------------------ 
ex. 
car_model CHAR(10); 
------------------------------------ 

⊙ VARCHAR (M) 

VARCHAR 데이타 타입은 가변적인 길이의 문자열을 저장하므로 CHAR 보다는 좀더 융통성 있 
는 데이타 타입이다. 
VARCHAR 문자열은 1-255 자 범위의 문자를 저장할 수 있다. 
(CHAR 는 포함된 데이타의 크기에는 관계없이 이미 지정된 가변적인 전체의 길이를 저장하 
는 반면에 VARCHAR 는 오직 들어가는 데이타의 양만을 저장하므로 데이타베이스 파일의 크 
기를 줄 일수 있다.) 

------------------------------------ 
ex. 
car_model VARCHAR(10); 
------------------------------------ 

⊙ INT (M) [Unsigned] 

INT 데이타타입은 -2147483648 에서 2147483647 사이의 정수를 저장한다. 
"unsigned" 옵션과 함께 0부터 4294967295 범위의 정수를 나타낼 수도 있다. 

----------------------------------------------------------- 
ex. 
light_years INT; 
Valid integer: '-24567'. Invalid integer: '3000000000'. 
----------------------------------------------------------- 
ex. 
light_years INT unsigned; 
Valid integer: '3000000000'. Invalid integer: '-24567'. 
----------------------------------------------------------- 

⊙ FLOAT [(M,D)] 

FLOAT는 다소 정확한 숫자의 표시가 필요할 때 사용되어지며, 작은 양의 소수점 숫자를 나 
타낸다. 

------------------------------------ 
ex. 
rainfall FLOAT (4,2); 
------------------------------------ 
이것은 소수점 값이 될 수 있는 일년간 평균강수량을 나타낼 수 있다. 좀 더 명확하게 
말하면 FLOAT (4,2) 는 4개의 저장할 수 있는 최대 자리 수와 2개의 소수점 이하의 자리 수 
를 가리킨다. 

42.35 은 올바른 값이다. 
324.45 은 틀린 값이다. 324.5로 해야 맞다. 
2.2 은 올바른 값이다. 
34.542 은 틀린 값이다. 34.54로 해야 맞다. 

주의) FLOAT 는 어림잡은 수이기 때문에 MySQL 내에 포함 된 정수의 값이 아닌 데이타 타입 
으로 돈의 값을 나타낼 때에는 DECIMAL을 사용하는 것이 더 현명한 방법이다. 더욱 자세 
한 설명을 원하면 매뉴얼을 참고하기 바란다. 


⊙ DATE 

날짜와 관련된 정보를 저장한다. 디폴트 형식은 'YYYY-MM-DD' 이며, '0000-00-00' 에서 
'9999-12-31'까지의 범위를 갖는다. MySQL은 이 기사에서는 다루어지기 너무 방대한 막강 
한 날짜형식의 조절과 조작 명령어를 제공한다. MySQL 매뉴얼에 이 기능에 대해서 
자세하게 다루어져 있으므로 참고하기 바란다. 
------------------------------------ 
ex. 
the_date DATE; 
------------------------------------ 

⊙ TEXT / BLOB 

text 와 blob 데이타 타입은 255 - 65535 자의 문자열을 저장할 때 사용된다. 이것은 여 
러분이 읽은 기사와 같은 것을 저장하기에 유용하다. 그러나 VARCHAR 와 CHAR처럼 딱 잘 
라 비교할 수는 없다. 단지 BLOB 와 TEXT 사이에 차이점이 있다면 BLOB은 변하기 쉬운 
경우에 비유할 수 있고, TEXT는 영향을 받지 않는 무감각한 경우에 비유할 수 있다. 


⊙ SET 

지정된 값으로부터 어떤 주어진 값을 선택하는, 정해진 문자열의 데이타 타입으로 그것은 
하나의 값이 될 수도 있고 여러개의 값을 가질 수도 있다. 64개의 값까지 지정할 수 있다. 
------------------------------------------- 
ex. 
transport SET ("truck", "wagon") NOT NULL; 
------------------------------------------- 

위의 예로부터 수송기관(transport)은 다음의 값들을 가질 수 있다. 

------------------------------------ 
"" 
"truck" 
"wagon" 
"truck","wagon" 
------------------------------------ 

⊙ ENUM 

SET 데이타 타입과 비슷한 특징을 갖는 정해진 문자열의 데이타 타입이지만 선택할 수 있는 
값이 하나로만 정해져 있다는 점이 다르다. 한 공간의 바이트만을 가지므로 테이블내의 
시간과 공간을 절약할 수 있다. 


------------------------------------------- 
ex. 
transport ENUM ("truck", "wagon") NOT NULL; 
------------------------------------------- 
위의 예로부터 수송기관(transport)은 다음의 값들을 가질 수 있다. 

------------------------------------ 
NULL 
"truck" 
"wagon" 
"truck" 
------------------------------------ 


2.2 레코드 


데이타들은 관련된 것들끼리 묶여서 디스크에 저장되는데 이러한 데이타의 묶음을 레코드라 
고 한다. 레코드는 데이타저장의 기본단위이며, 하나의 레코드는 서로 다른 형태의 값(데이 
타타입)을 가질 수있다. 아래에 나열된 이름, 주소, 전화번호는 각각 세개의 부분으로 구성 
된 레코드로 저장할 수 있으며 이러한 레코드는 데이타가 저장되는 기본단위로서 하나의 
테이블을 구성한다. 

이름 | 주소 | 전화번호 
--------|-------|--------- 
원주희 | 한국 | 007-0000 
홍길동 | 북한 | 008-0909 


2.3 테이블(The Bigger Picture: Tables) 
-------------------------------------- 

우리는 데이타베이스 상에서 어떠한 명령어들을 수행하기 전에, 먼저 데이타가 저장될 수 
있는 테이블을 만들어야 한다. 이것은 다음과 같은 방법으로 만들어진다. 

------------------------------------ 
mysql> CREATE TABLE test ( 
> name VARCHAR (15), 
> email VARCHAR (25), 
> phone_number INT, 
> ID INT NOT NULL AUTO_INCREMENT, 
> PRIMARY KEY (ID)); 
------------------------------------ 
테이블이 성공적으로 만들어지면 다음과 같은 화면이 출력될 것이다. 

------------------------------------ 
Query OK, 0 rows affected (0.10 sec) 
mysql> 
------------------------------------ 

여러분의 데이타베이스에 첫 번째 테이블이 생성되었다. 
주의(1) : 서로 다른 두 개의 테이블은 같은 이름을 가질 수 없다. 
주의(2) : 각각의 데이타공간은 종종 컬럼(column)이라는 개체의 속성으로 나타낸다. 

컬럼(Column)의 특징 : 
------------------------------------ 
하나의 이름이 숫자로만 구성될 수 없다. 
하나의 이름은 숫자로 시작할 수 있다. 
하나의 이름은 64자까지 가능하다. 
------------------------------------ 

2.3.1 테이블의 다른 옵션들 : 

나중에 다른 특징들과 성능이 데이타 타입에 추가될지라도 다음의 옵션들은 계속 존재할 것이다. 

기본 키(Primary Key) : 
===================== 
다른 속성들로부터 하나의 레코드를 유일하게 식별하는데 사용되어지며, 두 개의 레코드는 
똑같은 기본 키를 가질 수 없다. 이것은 두개의 레코드가 중복되어지는 실수를 없애려 
고 할 때 아주 적합하게 사용된다. 

Auto_Increment : 
================ 
이 함수(function)를 가진 컬럼(column)은 레코드에 삽입될 때 자동적으로 한 개씩 값이 
(previous + 1) 증가한다. data가 'NULL'값 일 때도 컬럼(column)에 자동적으로 한 개씩 
값이 증가하여 삽입된다. 

NOT NULL : 
========== 
NULL값(값이 없는)을 절대로 허용하지 않는 컬럼(column)을 의미한다. 

------------------------------------ 
ex. 
soc_sec_number INT PRIMARY KEY; 
------------------------------------ 
두 개의 soc_sec_number 레코드는 같은 값을 가질 수 없다. 

------------------------------------ 
ex. 
ID_NUMBER INT AUTO_INCREMENT; 
------------------------------------ 
1 에서 시작한 ID_NUMBER 값은 다음 값이 입력될 때마다 자동적으로 1씩 증가한다. 


2.3.2 테이블과 관련된 명령어들 

우리는 다음과 같이 테이블에 관련된 많은 유용한 명령어들을 실행할 수 있다. 


⊙ Show Tables 
============== 
------------------------------------ 
mysql> show tables; 
------------------------------------ 
결과 : 데이타베이스에 현재 존재하고 있는 모든 테이블들을 나열한다. 

⊙ Show Columns 
=============== 
------------------------------------ 
mysql> show columns from test; 
------------------------------------ 
결과 : 지정된 테이블과 관련된 컬럼과 컬럼의 정보를 보여줄 것입니다. 

테스트용 테이블을 생성한 후에 위의 명령어들을 한번씩 실행해보기 바란다. 
복잡 다양한 데이타베이스의 이해에 매우 도움이 될 것이다. 


여러분은 이제 MySQL 서버의 가장 중요한 개념인, 테이블을 생성하는 기본적인 과정을 이해 
했다. 또한 테이블은 서로다른 형태의 데이타타입으로 이루어진 레코드가 모여 구성된다는 
것도 알았다. 다음 장에서는 데이타베이스를 조작하는 방법에 대해 설명할 것이다. 



● Part 3: 데이타베이스 다루기(Manipulating the Database) 
======================================================== 

데이타베이스는 다음의 4가지의 방법으로 조작할 수 있다. : addition, deletion, 
modification, 과 search : 이에 대해서는 다음 장에서 자세히 설명할 것이다. 많은 
컴퓨터 언어들처럼 SQL 역시 조금은 특별한 명령어 구문을 가지고 있다. 괄호(()), 콤 
마(,), 또는 세미클론(;)의 위치가 조금만 잘못되어도 에러가 발생하므로 주의해서 입력해 
야 한다. 


3.1 레코드 입력하기(Insertion of records) 


전에 설명한 test라는 테이블 만드는 방법을 다시 한번 살펴보자. 

------------------------------------ 
mysql> CREATE TABLE test ( 
> name VARCHAR (15), 
> email VARCHAR (25), 
> phone_number INT, 
> ID INT NOT NULL AUTO_INCREMENT, 
> PRIMARY KEY (ID)); 
------------------------------------ 


이미 만들어진 테이블에 데이타를 입력하기 위해서는 INSERT 문을 사용한다. 

------------------------------------ 
mysql> INSERT INTO test VALUES 
mysql> ('Bugs Bunny', 'carrots@devshed.com', 
mysql> 5554321, NULL); 
------------------------------------ 
성공적으로 입력이 되면 다음과 같은 메시지가 나온다. 
--------------------------------------------------- 
Result, assuming the command was correctly entered: 

Query OK, 1 row affected (0.02 sec) 
mysql> 
--------------------------------------------------- 

· VARCHAR 데이타타입은 단일인용문으로 둘러싸여 있다. 모든 문자열 타입의 데이타타입 
은(char, varchar, text, blob 등)단일 인용문으로 둘러싸여야 하며 그렇지 않으면 
에러가 발생한다. 
· phone number와 같은 INT 타입의 데이타타입은 단일인용문이 필요하지 않다. 
· NULL은 아직정해지지않은 값으로 값이 없을 수도 있지만 NOT NULL은 반드시 값을 입력 
해야한다. AUTO_INCREMENT와 사용된 레코드는 값이 NULL이면 1을 할당하고, 값이 있 
으면 이전값에 +1씩 자동적으로 부여한다. 

한가지 주의해야 할점은 데이타를 입력할때 반드시 레코드의 갯수만큼의 데이타를 입력해 
야한다. 위의 예에서는 4개의 값을 입력해야 하는데 한개의 값만 입력할 경우 다음과 같은 
에러가 발생한다. 
-------------------------------------------------- 
Ex. 
mysql> insert into test values('doggy'); 
ERROR 1058: Column count doesn't match value count 
mysql> 
-------------------------------------------------- 

MySQL의 가장 큰 장점중의 하나는 데이타타입을 자유롭게 변경할 수 있다는 것이다. 


3.2 테이블정보 검색하기(Selection) 

데이타를 검색하기 위해 SELECT문을 사용한다. 
------------------------------------ 
mysql> SELECT * FROM test 
mysql> WHERE (name = "Bugs Bunny"); 
------------------------------------ 
결과: 
+------------+--------------------+--------------+----+ 
| name | email | phone_number | ID | 
+------------+--------------------+--------------+----+ 
| Bugs Bunny | carrot@devshed.com | 5554321 | 1 | 
+------------+--------------------+--------------+----+ 

같은 이름이지만 서로 다른 email와 phone number를 가진 데이타를 입력해보자. 

+------------+---------------------+--------------+----+ 
| name | email | phone_number | ID | 
+------------+---------------------+--------------+----+ 
| Bugs Bunny | carrot@devshed.com | 5554321 | 1 | 
| Bugs Bunny | pepper@devshed.com | 5554331 | 2 | 
| Bugs Bunny | celery@devshed.com | 5554351 | 4 | 
| Bugs Bunny | lettuce@devshed.com | 5554341 | 3 | 
+------------+---------------------+--------------+----+ 

3.3 삭제하기(Deletion) 

테이블에 있는 한개 이상의 레코드를 삭제하기 위해 사용한다. 
DELETE문으로 수행된다. 
------------------------------------ 
mysql> DELETE FROM test 
mysql> WHERE (name = "Bugs Bunny"); 
------------------------------------ 
결과 : 이름이 Bugs Bunny인 레코드를 도두 삭제하므로 테이블에는 데이타가 
하나도 없다. 

------------------------------------ 
mysql> DELETE FROM test 
mysql> WHERE (phone_number = 5554321); 
------------------------------------ 
결과 : phone_number 가 5554321인 레코드를 삭제한다. 
+------------+---------------------+--------------+----+ 
| name | email | phone_number | ID | 
+------------+---------------------+--------------+----+ 
| Bugs Bunny | pepper@devshed.com | 5554331 | 2 | 
| Bugs Bunny | celery@devshed.com | 5554351 | 4 | 
| Bugs Bunny | lettuce@devshed.com | 5554341 | 3 | 
+------------+---------------------+--------------+----+ 


3.4 데이타 변경하기(Modification) 

테이블에 이미 입력된 자료를 변경하기 위해 사용되며 UPDATE 문을 사용한다. 
------------------------------------------ 
mysql> UPDATE test SET name = 'Daffy Duck' 
mysql> WHERE name = "Bugs Bunny"; 
------------------------------------------ 

+------------+---------------------+--------------+----+ 
| name | email | phone_number | ID | 
+------------+---------------------+--------------+----+ 
| Daffy Duck | pepper@devshed.com | 5554331 | 2 | 
| Daffy Duck | celery@devshed.com | 5554351 | 4 | 
| Daffy Duck | lettuce@devshed.com | 5554341 | 3 | 
+------------+---------------------+--------------+----+ 

● Part 4: 고급 MySQL명령어(Advanced MySQL Commands) 
==================================================== 

우리는 이제 MySQL에 대해 기본적인 개념과 명령어들에 대해 배웠다. 이번장에서는 
좀더 진보된 명령어에 대해 배워보기로 하겠다. 


4.1 논리 연산자(Logical Operations) 

MySQL은 모든 기본적인 논리연산자를 지원한다. 

⊙ AND (&&) 
------------------------------------ 
mysql> SELECT * FROM test WHERE 
mysql> (name = "Bugs Bunny") AND 
mysql> (phone_number = 5554321); 
------------------------------------ 
결과 : 이름이 "Bugs Bunny"이고 전화번호가 '5554321'인 레코드가 출력될것이다. 

⊙ OR ( || ) 
------------------------------------ 
mysql> SELECT * FROM test WHERE 
mysql> (name = "Bugs Bunny") OR 
mysql> (phone_number = 5554321); 
------------------------------------ 
결과 : 이름이 "Bugs Bunny"이거나 전화번호가 '5554321'인 레코드가 모두 출력된다. 

⊙ NOT ( ! ) 
------------------------------------ 
mysql> SELECT * FROM test WHERE 
mysql> (name != "Bugs Bunny"); 
------------------------------------ 
결과 : 이름이 "Bugs Bunny"이 아닌 레코드만 출력된다. 

⊙ Order By 
------------------------------------ 
mysql> SELECT * FROM test WHERE 
mysql> (name = "Bugs Bunny") ORDER BY 
mysql> phone_number; 
------------------------------------ 
결과 : 이름이 "Bugs Bunny"인 모든 레코드가 phone_number를 기준으로 정렬될것이다. 


4.2 Search functions 

MySQL 은 일반문자뿐만아니라 특수문자를 포함해 데이타를 검색할 수 있다. 찾고자하는 
값을 정확히 모를때 Like연산자를 사용해 문자형태가 같은 열을 검색한다. 

------------------------------------ 
mysql> SELECT * FROM test WHERE 
mysql> (name LIKE "%gs Bunny"); 
------------------------------------ 
결과 : 
· "gs Bunny"를 포함하는 모든 레코드가 출력될 것이다. 
("Bugs Bunny", "ags Bunny", "gs Bunny", 와 "234rtgs Bunny"등과 같은 이름) 

· "LIKE"가 equals sign(=)대신 사용된것에 주목하자. "LIKE"는 정확한 값을 모르는 
데이타를 검색할때 사용된다. 

· '%'는 임의의 문자(0개~임의의 개수)를 의미하며, '_'는 한문자를 의미한다. 

------------------------------------ 
mysql> SELECT * FROM test WHERE 
mysql> (name LIKE "Bugs Bunny%"); 
------------------------------------ 
결과 : "Bugs Bunny"를 포함하는 문자가 출력될 것이다. 
("Bugs Bunnys", "Bugs Bunnyyyy453", "Bugs Bunnytrtr"등과 같은 이름, 
그러나 "gs Bunny"는 아니다.) 


4.3 주어진 조건에 맞는 특정한 열만 검색하기(Focused Search Results) 
------------------------------------ 
mysql> SELECT name FROM test WHERE 
mysql> (name = "Bugs Bunny"); 
------------------------------------ 
결과 : 
+------------+ 
| name | 
+------------+ 
| Bugs Bunny | 
+------------+ 


4.4 테이블 변경하기(Alter table) 

MySQL의 가장 중요한 기능중의 하나가 이미 만들어진 테이블을 변경하는 것입니다. 
ALTER 문을 사용하며 다음과 같은 것을 수행할 수 있습니다. 
· 새로운 열 추가하기 
· 열의 속성 바꾸기 
· 열 삭제하기 
· 테이블 이름 바꾸기 

Example: 테이블 이름 변경하기(Rename the table) 
-------------------------------------------- 
mysql> ALTER table test RENAME mytest; 
-------------------------------------------- 

Example: 새로운 열 추가하기(Add a column) 
-------------------------------------------- 
mysql> ALTER table mytest ADD birthday DATE; 
-------------------------------------------- 

Example: 열의 속성변경하기(Modify a column) 
-------------------------------------------- 
mysql> ALTER table mytest CHANGE 
mysql> name newname VARCHAR (25); 
-------------------------------------------- 

Example: 열 삭제하기(Delete a column) 
-------------------------------------------- 
mysql> ALTER table mytest DROP newname; 
-------------------------------------------- 

이제 아래에 주어진 테이블을 만들어 보고 테이블을 변경해 보자. 
-------------------------------------------- 
mysql> TABLE mytest ( 
> email VARCHAR (25), 
> phone_number INT, 
> ID INT AUTO_INCREMENT, 
> birthday DATE ); 
--------------------------------------------  

Posted by SB패밀리

MYSQL Query의 간단한 사용법


http://www.nzeo.com/bbs/zboard.php?id=p_study&page=2&sn1=&divpage=1&category=67&sn=off&ss=on&sc=off&select_arrange=headnum&desc=asc&no=72000-03-06 03:25:23,


1. MYSQL DB
PHP에서 DB와 연동하기 위해서는 우선 DB에 접근을 해야 합니다.
DB에 접근하기 위해서는 MYSQL DB가 어데 있는지와 자신의 계정 아듸와, 패스워드, 
그리고 DB계정 아듸가 필요합니다.
보통 MYSQL DB는 자신의 계정과 같은 곳에 있기 때문에 localhost로 지정하면 되지만 따로 서버를 
만들어서 MYSQL DB를 이용하는 경우에는 해당 서버의 IP 주소가 필요합니다.
그럼 실질적으로 하겠습니다.
우선 DB에 접속하기 위한 설정을 변수로 미리 선언해 놓습니다. (이게 편합니다)

$host_name = "localhost";
$user_name = "user";
$user_password = "*****";
$db_name = "test";

즉 Mysql의 DB는 같은 계정에 있다구 하고, $user_name은 자신의 계정 아듸, $user_password는 계정 패스워드, $db_name은 자신에게 할당된 DB의 이름입니다.

그럼 이제 접속을 해야 겠죠.

$connect = mysql_connect($host_name,$user_name,$user_password) or echo"mysql_error()"; 

mysql_connect()라는 함수가 바로 DB에 접속하는 함수입니다.
mysql_connect() 함수에 $host_name, $user_name, $user_password를 주고 호출을 하게 되면 결과가 나옵니다.
이 결과값은 $connect 안에 넣게 되죠.
뒤에 or echo"mysql_error()"; 은 만약 에러가 발생하면 에러값을 출력하게 하는 구문입니다.
mysql_error()은 에러발생시 에러값을 return 해 주는 기특한 함수입니다.
만약 이상없이 DB에 접속하게 되면 아무 표시도 안나겠죠.
그럼 이제 자신의 DB에 연결해 봅시다.

mysql_select_db($db_name, $connect ) or echo"mysql_error()";

mysql_select_db()에 $db_name 과 $connect를 넣구 호출하면 자신의 DB에 연결이 됩니다.

2. Table 생성

자 그럼 이제 DB에 테이블을 생성해 봅시다.
DB에 테이블을 생성하건, 삭제하건, 아님 수정하건 Query문을 mysql에 건네주게 되어 있습니다.

이름과 나이, 전화번호, 주소만 가지고 있는 테이블을 만들어 봅시다.
$que = "CREATE TABLE Human_info (
                                      id int(11) DEFAULT '0' NOT NULL auto_increment,
                                      name varchar(10),
                                      age int(3),
                                      tel_num varchar(20),
                                      address text,
                                      PRIMARY KEY (id))";

위와 같은 Query문을 만들었습니다.
Query문을 만들 때는 문자열 변수에 내용을 입력하면 됩니다.
위에 것은 보기 좋으라고 줄을 나누었는데 이러기 싫은 한줄로 쫘악 해도 됩니다.

생성하는 Query문은 "CREAT TABLE 테이블명 ( 필드명과 Type )" 로 합니다.
즉 위에서 테이블명은 Human_Info가 되죠.
그리고 id, name, age, tel_num, address 같은 넘은 바로 스키마 이름이 되는 것이고, 그 옆에 int(11), 
varchar(10), text 같은 것은 Type이 되는거죠.
그런데 사용할 스키마와는 별도로 id 라는 스키마를 지정했죠?
ID는 테이블에 데이터를 넣고 뺄 때 필요한 일련번호입니다.
DEFAULT '0' 은 첨에는 0부터 시작한다는 거죠.
NOT_NULL 은 절대 빈칸은 허용 안되다는 거죠. 어떤 넘이라도 일련번호를 붙여야 된다는 거죠.
auto_increment 는 별다른 값을 안 주어도 자동으로 증가하라는 겁니다.
그리고 밑에 PRIMARY KEY (id)를 씀으로서 기본키는 ID라는 것을 지정하는 겁니다.

그럼 위에 쓰인 Type에 대해서 이야기 하죠.
int(11)은 11자리의 정수형 타입닙니다.
varchar(20)은 20칸짜리 문자열이라는 거구요.
text는 개행문자를 포함하는 끝을 모르는(?) 문자열이라는 겁니다.
Type은 보통 위에 3가지만 쓰면 별 이상없을 겁니다.
다른 Type들은 별로 쓰이지는 않으니 필요할때마다 찾아서 하시면 됩니다.
자 그럼 이 $que 라는 질의어를 mysql에 전달합시다.

mysql_query( $que, $connect ) or echo"mysql_error()";

mysql_query() 라는 함수가 바로 질의어를 넘겨주는 함수입니다.
물론 생성할 때뿐만 아니라 질의어를 넘겨줄 때 이 함수를 쓰는 겁니다.

이렇게 하면 자신의 DB에는 id, name, age, tel_num, address를 필드로 하는 테이블이 생성된겁니다.

3. Table에 자료 추가

자 이제, 테이블을 생성했으니 자료를 추가해봅시다.
지금은 테이블만 만들어져있기 때문에 자료가 하나도 없습니다.
자료를 Insert할 때는 필드의 순서대로 입력을 해야 합니다.
우선 Query 문을 작성해 봅시다.

$que = "INSERT INTO Humna_info VALUES (
                            '',
                            '아무개',
                            24,
                            '000-000-0000',
                            '아무시 
                            아무구 아무동'
                            )";

위의 "INSERT INTO 테이블명 VALUES (데이타...)" 라구 하는 것이 자료추가하는 질의어입니다.
VALUES ( 다음에 보면 처음에 '' 라고 되어 있죠?
이넘이 바로 id입니다. 즉 인위로 값을 넣지 않죠.
하지만 위에서 정의한 대로 auto_increment 이기 때문에 저절루 순서가 매겨집니다.
그리고 2번째 이름은 문자열 이기 때문에 '로 둘러싼 것 입니다. (" 쓰면 안됩니다.)
그리고 3번째 나이는 정수형이기 때문에 ' 가 필요없습니다.
이 질의어를 mysql_query를 통해서 MySQL에 일을 냅따 시킵시다.

mysql_query( $que, $connect ) or echo"mysql_error()";

그럼 이제 Human_Info라는 테이블에는 id 값이 0인 첫 번째 값이 들어간거죠.

4. Table의 자료 제거
이제 만들어 봤으니 제거 하는 방법을 알아 봅시다.
제거하는 방법은 추가하는 것보다 더 쉽습니다.

$que = "delete from Human_info where id=0";
mysql_query( $que, $connect );

delete from 테이블명 where 조건문 하면 됩니다. 그러고 $que를 MySQL에 넘겨주면 지웁니다.

위이 예에서는 Human_Info라는 테이블에서 id값이 0인 넘을 지우라는 거죠.
where id=0 했으니깐요.
만약 where age=20 하면 Human_info 테이블에서 age=20 인넘들은 모두 지우죠.

5. Table의 자료 수정
자료의 수정방법도 매우 쉽습니다.

$que = "UPDATE Human_Info SET name='막둥이' WHERE id=0";
mysql_query( $que, $connect );

수정할 때는 "UPDATE 테이블명 SET 수정할넘=수정할값 WHERE 조건문" 하믄 됩니다.

콤마(,)를 이용해서 여러개를 바꿀수 있습니다.

6. Table의 자료 출력

자 이제 만들고, 지우고, 수정하는 걸 알았으니 원하는 자료를 테이블에서 불러오는 방법을 해봅시다.

$que = "SELECT * FROM Human_Info";
$data = mysql_query( $que, $connect );

바로 SELECT, FROM을 이용해서 가져옵니다.
* 는 모든 것을 가져오라는 겁니다.
만약 name만 필요하다면 SELECT name FROM Human_Info 라구 하면 되고요.
name과 age가 필요하면 SELECT name, age FROM Human_Info 라고 하면 되죠.

Query문을 mysql_query를 통해서 MYSQL에 전달하면 mysql_query() 함수는 찾은 결과를 return 하게 됩니다.
위에서는 $data라는 변수에 결과값을 저장하였죠.
그럼 $data 변수안에는 찾은 결과가 배열의 형태로 입력되어져 있습니다.
그럼 우선 몇 개가 찾아졌는지 함 알아봅시다.

$total = mysql_affected_rows();

위와 같이 하면 총 몇 개가 찾아졌는지 알수 있습니다.
mysql_affected_rows() 이라는 함수는 찾아진 값의 갯수를 return 합니다.

자 그럼 이제 $data안에 있는 내용을 출력하기로 해봅시다.

출력하기 위해서는 mysql_data_seek($data,$i) 라는 함수를 알아야 합니다.

mysql_data_seek()는 $data 파일에서 $i 번째의 데이터를 지정시켜 놓는 함수입니다.

즉 mysql_data_seek($data,0) 이라고 하면 찾아진 결과의 첫 번째 데이타를 지정해 놓는 거죠.

지정을 했으면 다음과 같은 방법으로 값을 가져옵니다.

$human = mysql_fetch_array( $data );

mysql_fetch_array()는 $data에서 지정된 넘의 값을 배열로 return 합니다.
즉 $human[id], $human[name], $human[age], $human[tel_num], $human[address] 가 되는거죠.

출력할 때는 echo"이름 : $human[name], 나이 : $human[age]살"로 하면 되죠.

이름 : 아무개, 나이 : 20살

위에 처럼 출력 되겠죠.

그럼 리스트처럼 주르륵 하기 위해서는 for문을 사용하면 됩니다.

for($i = 0; $i < $total; $i++)
{
mysql_data_seek($data,$i);
$human = mysql_fetch_array( $data );
echo"이름 : $human[name], 나이 : $human[age]살 
";
}

위와 같이 하면 주르륵 나오겠죠?

쉽죠?

그럼 select 문에 대해서 몇가지만 더 적겠습니다.

$que = "SELECT * FROM 테이블명 order by id";

위에 처럼 하면 order by id 라는 구문 때문에 id의 정렬순으로 결과가 나옵니다.

만약 역순으로 할려면 order by id desc 라고 하면 되지요.

그리고 limit 숫자 하면 숫자만큼의 갯수만 나옵니다.
$que = "SELECT * FROM 테이블명 order by id limit 10";
위에 처럼 하면 10개만 나오죠.

만약 검색처럼 어떤 문자열을 포함하고 있는 넘을 찾을 때는 다음과 같이 하면 됩니다.
이름에 "김"이 포함된 넘을 찾는 다고 합시다.
$que = "SELECT * FROM 테이블명 WHERE name LIKE '%김%'";
위에서 WHERE라는 넘은 아까도 나왔지만 조건을 붙일 때 쓰는 넘입니다.
그리고 LIKE '%검색문자%' 라구 덧 붙이면 name 필드중 "김" 이라는 문자가 있는 넘을 찾아라는 겁니다. 

Posted by SB패밀리


데이터베이스를 백업 받는 방법은 크게 두 가지가 있습니다.
하나는 db 를 통째로 받는 방법과 table을 각각 받는 방법이 있습니다. 


1. 데이터베이스 백업하기 
1) db 를 통체로 받는 방법

mysql 은 /usr/local/mysql 에 설치 되어 있습니다.

방법 : /usr/local/mysql/bin/mysqldump -u username -p dbname > dbback.sql
password : <=== 패스워드 입력

위와 같이 하시면 db 를 통째로 모두 받으실 수 있습니다.

2) db 의 특정 table 만 받는 방법

방법 : /usr/local/mysql/bin/mysqldump -u name -p dbname tablename > tableback.sql
password : <=== 패스워드 입력

위와 같이 백업을 받으시고 파일로 다른 디렉토리나 ftp 를 사용하셔서 다운 받아 놓으면 mysql 에러시 복구를 할 수 있어 데이터 손실률을 최소로 할 수 있습니다.  



2. 데이터베이스 복구하기 
1) db 서버에서 db 가 없어졌을 경우 

db를 먼저 만드신 다음에 table 복구 방법처럼 복구하시면 됩니다.
시스템 관리자가 아니라면 db 를 만들수 없으므로 이럴 경우에는 시스템 관리자에게 데이터베이스를 새로 생성해 줄 것을 요청하시면 됩니다.
참고로 db 를 만드는 방법은 아래와 같습니다.

/usr/local/mysql/bin/mysql -u name -p
password : <=== 패스워드 입력
create database dbname;

이런식으로 만드시면 됩니다.

2) table 백업 복구 방식

/usr/local/mysql/bin/mysql -u name -p dbname < tableback.sql
password : <=== 패스워드 입력

위와 같이 백업과 복구가 가능합니다.  


참고 파일 디렉토리 백업 및 복구 방법 

[백업] 
tar -cvf filename.tar targetfile 

[복구] 
tar -xvf targetfile [target directory]

[압축보기]
tar -tvf targetfile

Posted by SB패밀리


[PHP/DB] Database, MySQL 이란 무엇인가


http://www.nzeo.com/bbs/zboard.php?id=p_study&page=2&sn1=&divpage=1&category=67&sn=off&ss=on&sc=off&select_arrange=headnum&desc=asc&no=42000-03-06 03:21:32

우선 PHP문법에 들어가기 전에 간단하게 Database에 대해서 이야기하겠습니다.
얼마전까지만 해두 CGI라구 하면 펄을 생각하게 되었구 오라클이나 MySQL같은 DBMS(데이터베이스 관리시스템 : Database Management System)은 최소한 웹상에서는 들리지 않았습니다.
그런데 PHP라는 CGI 프로그래밍 언어가 등장하면서 DB라는 이야기가 많이 들리게 되었습니다.
그럼 왜 PHP는 펄과는 다르게 DB를 이용하는지, 그리고 이 DB가 무엇인지 간단히 이야기하겠습니다.
데이터 베이스는 데이터를 모아둔 것입니다.
예를 들면 학교 도서관의 도서 데이터베이스가 있겠죠.
즉, 도서관에 어떤 책이 들어왔는지, 그 책들의 작가는 누군인지, 누가 대여해갔는지 하는것들이 모두 데이터베이스 안에 들어있겠죠.
이런 데이터들은 가만히 있는 것이 아닙니다.
새로 책들이 들어왔을수도 있고, 폐기되었을수도 있죠. 누가 빌려갈수도, 반납할수도 있는겁니다.
즉, 데이터베이스는 이러한 요인들에 의해서 저장된 데이터를 변경할수 있어야 하죠.
이렇게 데이터베이스를 만들고 관리하는등의 일을 하는 프로그램들을 데이터베이스 관리 시스템 (Database Managemenu System)이라고 합니다.
이 데이터베이스 관리 시스템이 하는일은 데이터를 저장하고 삭제하는 등의 일과 이 데이터들로부터 원하는 정보를 효율적이고 빠른 방법을 제공하는 것이겠죠.
이렇게 데이터베이스에서 데이터를 관리하기 위해서 데이터베이스에 명령을 전달하게 하는 언어를 데이터베이스 관리언어(DBME)라고 합니다.
DBME는 Query라는 데이터베이스 관리 프로그램의 언어를 이용해서 데이터를 관리하게 됩니다.
이런 데이터베이스 관리시스템들은 다양한 종류가 있습니다.
공개되어 있는, 그리고 우수한 성능을 가지고 있어서 널리 알려진 MySQL도 있구, 상용인 오라클도 있고, 그외에 mSQL, PostgreSQL등도 있습니다.
우리가 사용할 MySQL은 무료로 쓸수 있게 공개된 관계형 데이터베이스로서 일반 상용에 비해서 별루 뒤질것이 없는 좋은 프로그램입니다.
안정성 및 무결성의 측면에서 여타 상용 데이터베이스에 비해서 떨어진다고는 한다지만 관리만 잘하면 매우 유용하게 사용할수 있습니다.
MySQL의 주요목표는 속도, 뛰어난 수행능력 그리고 사용의 편리함입니다.
처음에 MySQL은 TcX 내부에서 자체적으로 사용할 목적을 가지고 만들어졌다고 합니다.
TcX는 1996년부터 MySQL을 사용해 왔으며 현재 700만 레코드이상되는 500개 이상의 테이블(100기가 바이트 이상)이 주요업무에 사용되고 있다고 하니 어느정도의 중소업체에서도 충분히 사용할 수가 있습니다.
데이터 베이스 관리 시스템이 어떠한 식으로 데이터를 관리하는지에 대해서는 언급하지 않겠습니다.
물론 저도 잘 모릅니다.
그럼 직접적으로 우리가 알아야 하는 것을 이야기하겠습니다.
보통 MySQL을 지원하는 계정에서는 회원들에게 하나의 DB를 줍니다.
근데 잘 모르는 분덜은 왜 하나만 주나, 나는 게시판 여러개 하구 방명록도 DB를 이용하는 넘으로 할건데~ 하구 의아해하시는 분덜이 계실겁니다.
결과부터 말하자면 하나의 DB안에는 많은 수의 게시판이나 방명록등의 데이터를 저장할수 있습니다.
DB를 이용하는 PHP 게시판들은 데이터를 테이블에 저장합니다.
이 테이블은 하나의 DB안에 무한정은 아니지만 MySQL이 허락하는한 만들수 있습니다.
MySQL과 같은 관계형 데이터베이스는 모든 데이터를 테이블과 같은 형태로 나타내어 저장합니다.
테이블에 대해서 간단히 이야기하겠습니다.
일반적으로 보통 표라는 것을 많이 이용합니다.
시간표 같은것 말입니다.
예를 들문 시간표는 가로줄을 요일, 세로줄을 시간으로 해서 만들면 매우 편하게 만들수가 있습니다.
데이터베이스도 마찬가지입니다. 저장되는 데이터를 테이블(표)와 같은 형식으로 저장하고 관리를 합니다.
여러가지의 속성을 가진 대상들의 데이터를 테이블의 형태로 만드는 것입니다.
시간표를 예를 들면 월, 화, 수요일등과 같은 대상의 속성을 정의하여 만든 틀을 스키마라고 합니다.
만약 학생의 예를 들면 학생=(이름, 학번, 학과, 학점) 등과 같은 스키마를 가지게 만들수 있습니다.
게시판을 예로 들자면 게시판=(번호, 글쓴이, 메일주소, 홈페이지 주소, 제목, 내용, 조회수, 글쓴날자)등과 
같이 스키마를 만들수 있겠죠.
이런 스키마의 틀로 이루어진 테이블을 가지고 php 게시판등에서는 데이터를 저장, 삭제, 수정하는등의 관리를 하게 됩니다.
사실  PHP로 DB를 이용하는 CGI 프로그램을 만들기 위해서는 이 정도의 개념만 잡혀 있으면 충분하다고 봅니다.
그만큼 PHP 자체내에서 DB를 쉽게 이용하게 할수 있는 함수들이 제공되고, 또 MySQL의 Query문도 매우 쉽기 때문입니다.

참고로 PHP를 사용하는데 있어서 아파처서버가 권장됩니다.
A.P.M 이라는 말을 들어보셨는지요.
Apache , PHP, MySQL이라는 말입니다.
원래 PHP가 아파치서버와 MySQL을 배경으로 해서 만들어졌다고 합니다.

Posted by SB패밀리

오라클 테이블 존재여부 확인하기 


오라클 테이블 존재 여부 알아보기
-- table_name은 대문자로만 저장되기 때문에 찾을 문자열을 대문자로 바꿔서 비교해야 한다



SQL>SELECT TABLE_NAME 
        FROM USER_TABLES
        WHERE TABLE_NAME = UPPER('찾을 테이블 이름')

Posted by SB패밀리

[개발/MySQL] LOCK, 파일 제어 권한주기 





LOCK TABLES : 데이터베이스를 백업하거나 데이블의 스키마 구조를 변경하거나
기타 중요한 작업을 진행할 때 다른 사람이 해당 테이블에 작업을
하지 못하도록 막기 위해 locking을 함

   ex) mysql>create table locktest (no tinyint,name char(6));
mysql>insert into locktest values (1,'virus');
mysql>lock tables locktest read; => 읽기만 가능하고 쓰기는 금지

   *mysql>lock tables locktest read local; => local 사용자는 읽기만 가능, 다른사용자는 모두 가능
     (가상 콘솔 2번모드에서 insert 명령어로 데이터를 추가하면 추가가 되는것을 확인할수있다.)

   *mysql>lock tables locktest write; => 현재 사용자만 쓰고, 읽을수 있다
     (가상 콘솔 2번모드에서 insert 명령어로 데이터를 추가하면 아무런 반응이 없다
      unlock을 사용하여 locking을 풀어야 읽거나 쓸수있다.)

   *모든 테이블에 read 락을 걸려면 : mysql>flush tables with read lock;

mysql>insert into locktest values (2,'yuri');
mysql>select * from locktest;
mysql>unlock tables; => locking 해제

LOAD DATA INFILE 문법 : load data infile '파일명' into table 테이블명;

*load data infile 문을 사용하기 위해서는 file privilege(파일 제어 권한)이 있어야 한다. (jung라는 사용자와 jung2
    라는 사용자를 생성하고 jung2에게만 File privilege권한을 줘보자)

    mysql>create database jung;
mysql>use mysql;
mysql>insert into user (host,user,password) values ('localhost','jung',password('1234'));
mysql>insert into db values ('localhost','jung','jung','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');

mysql>create database jung2;
mysql>insert into user (host,user,password,File_priv) values ('localhost','jung',password('1234'),'Y');
mysql>insert into db values ('localhost','jung','jung','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql>flush privileges;

mysql>use jung;
mysql>create table filepriv (no tinyint,name char(6));
mysql>use jung2;
mysql>create table filepriv (no tinyint,name char(6));
mysql>quit

shell>cd /usr/local/mysql
shell>vi file.txt
1 aaa
2 bbb
3 ccc            //공백은 탭키 사용
shell>mysql -u jung -p jung
mysql>load data infile '/usr/local/mysql/file.txt' into table filepriv;   =>접근권한이 없다는 에러가뜬다.
mysql>quit
shell>mysql -u jung2 -p jung2
mysql>load data infile '/usr/local/mysql/file.txt' into table filepriv;   =>데이터 입력이 성공

Posted by SB패밀리

The Joel Test: 나은 코딩을 위한 12단계


글 : Joel Spolsky
번역 : B.K. Chung 정봉겸
감수 : Jang Han Goo 구장한
2000년 8월 9일

SEMA에 대해서 들어보신 적이 있습니까? 소프트웨어 팀이 얼마나 잘하는지를 재는 나름대로 복잡한 시스템입니다. 앗, 아니! 그 링크를 누르지 마세요. SEMA를 "이해"만 하는데 아마 6년정도가 걸릴것입니다. 그래서 소프트웨어 팀이 얼마나 좋은지 등급을 매길 수 있는 - 좀 무책임하고 되는대로의 - 자체적인 버젼의 테스트를 만들었습니다. 이 테스트의 장점은 3분정도밖에 걸리지 않는다는 것입니다. 절약되는 시간으로 의대에 가서 공부할 수도 있을 것입니다.

The Joel Test

  1. Source Control(소스 컨트롤)을 사용하십니까?
  2. 한번에 빌드를 만들어낼 수 있습니까?
  3. daily build(일별 빌드)를 만드십니까?
  4. 버그 데이타베이스를 가지고 있습니까?
  5. 새로운 코드를 작성하기 전에 버그들을 잡습니까?
  6. up-to-date(최신) 스케줄을 가지고 있습니까?
  7. spec(설계서)를 가지고 있습니까?
  8. 프로그래머들이 조용한 작업환경을 가지고 있습니까?
  9. 돈이 허락하는 한도내의 최고의 툴들을 사용하고 있습니까?
  10. 테스터들을 고용하고 있습니까?
  11. 신입사원들은 면접때 코드를 직접 짜는 실기시험을 봅니까?
  12. hallway usability testing(무작위 사용성 테스팅)을 하십니까?

Joel Test이 특별한 점은 각 직문에 예/아니오로 바로 대답할 수 있다는 것이다. lines-of-code-per-day(하루동안 산출되는 코드의 줄수)나 average-bugs-per-inflection-point(산출 시점의 평균 버그수) 같은 것은 알 필요가 없습니다. "예"에 해당 하는 질문에 1점씬 가산됩니다. 하지만 이 테스트는 핵 원자로에 사용하는 소프트웨어가 안전한지를 검사하는등 에는 사용하지 말아주십시오.

12점은 완벽, 11은 충분한 점수이지만 10점이나 그 이하는 심각한 문제가 있다는 신호입니다. 사실은 대개의 소프트웨어 회사 들이 2~3점을 받고 있고, 심각한 도움을 필요로 하고 있습니다. Microsoft같은 회사는 12점 만점을 받고 있습니다.

당연한 이야기지만 이것들만으로 성공과 실패를 가를 수는 없습니다. 특히, 아무도 필요없는 제품을 굉장히 훌륭한 소프트웨어 팀이 만들고 있다면, 역시나 아무도 원하지 않을 것입니다. 반대로 이런 방식을 따르지 않는 명인들이 세상을 바꾸는 소프트웨어 를 만드는 경우로 생각할 수 있겠습니다. 그러나, 이 12가지 이외의 요소를 모두 동등하게 놓고 본다면, 이들만 제대로 한다면 지속적으로 좋은 결과를 내는 잘 훈련된 팀이 될 것입니다.

1. Source Control(소스 컨트롤)을 사용하십니까?

상용 소스 컨트롤 패키지들도 사용해보았고, 무료로 사용할 수 있는 CVS도 사용해보았습니다. CVS는 무료이기는 하지만 충분합니다. 그렇지만 소스 컨트롤이 없다면 프로그래머들을 조율하는 일이 상당히 피곤할 것입니다. 프로그래머들은 다른 사람들이 어떤 것을 했는지 알 수 있는 방법이 없습니다. 이를 사용하면 실수를 쉽게 롤백할 수 있습니다. 소스 컨트롤의 다른 장점은 소스코드 자체가 모든 프로그래머의 하드디스크에 체크아웃(check out)되어 있다는 것입니다. 소스 컨트롤을 사용하는 프로젝트에서 코드를 날렸다는 이야기를 들어본 적이 없습니다.

2. 한번에 빌드를 만들어낼 수 있습니까?

"최신의 소스로부터 몇단계를 거쳐서 완제품(shipping build)을 만들 수 있습니까?"라는 의미의 질문입니다. 잘 되어있는 팀인 경우라면 하나의 스크립트로 checkout부터 시작하여 각 소스를 리빌드(rebuild)하고 각 버젼, 언어, #ifdef같은 조건별로 실행파일을 만들어내어 마지막 CDROM 레이아웃, 다운로드할 수 있는 웹사이트를 만들어 내는 정도까지 되어 있을 수 있겠습니다.

만일 이 과정이 하나의 단계 이상을 거친다면, 여기서부터 에러가 발생할 확률이 생깁니다. 정해진 기일이 가까워질수록 "마지막" 버그를 수정하고 실행파일을 만드는 등을 위해 빠른 사이클을 필요로 할 것입니다. 코드를 컴파일하고 설치파일을 구성하는데에 20단계가 필요하다면 급박한 시간때문에 사소한 실수를 저지르게 될 것입니다.

필자가 마지막으로 근무했던 회사에서는 이런 이유로 WISE를 InstallShield(역자주 : 두 제품 모두 설치본을 만들기위한 도구 입니다.)로 교체하였습니다. 설치 과정을 스크립트를 통해서 NT 스케줄러로 밤새에 자동으로 실행하도록 하고자 하였는데, WISE는 스케줄러로 실행할 수 없던 이유입니다. (WISE의 친절한 분들이 최신 버젼에는 이것이 가능하다고 알려왔습니다.)

3. daily build(일별 빌드)를 만드십니까?

소스 컨트롤을 사용하다 보면 누군가가 빌드를 실패하게 만드는 코드를 체크인 할 수 있습니다. 예를 들면, 새로운 소스파일을 추가해서 그 사람의 컴퓨터에서는 잘 컴파일되지만, 이를 코드 레파지토리(repository)에는 추가를 하지 않았을 수 있습니다. 이 사람은 이를 잊고 만족한 상태에서 컴퓨터를 잠그고 집에 돌아갑니다. 그렇지만 이로 인해 다른사람들은 작업을 할 수 없게 되고 결국 찝찝하지만 결과없이 집으로 돌아갈 수 밖에 없습니다.

모르는 사이에 빌드를 실패하는 이런 컴파일 오류가 나지 않도록 daily build를 만들게 됩니다. 큰 팀에서는 이런 경우를 위해서 daily build를 매일 오후 - 점심시간등 - 에 합니다. 사람들은 점심시간 이전에 될 수 있는 한 많이 체크인을 합니다. 점심을 먹으로 갔다가 다시 돌아오면 빌드는 이루어져 있습니다. 빌드가 실패하면, 사람들은 빌드가 성공한 이전 소스로 작업을 하면 됩니다.

엑셀팀에서는 누군가 빌드를 깨면 벌칙으로 다른 사람이 다시 깰때까지 빌드를 관리하도록 벌칙을 주었습니다. 이는 빌드를 깨면 받는 벌칙으로써 뿐만 아니라 모든 이들이 돌아가면서 빌드를 관리할 수 있게하여, 어떻게 돌아가는 지를 익히게 하는 방법으로써도 좋았습니다.

daily build에 관해 더 자세히 아시려면 저의 기사 daily builds are your friend를 읽으십시오.

4. 버그 데이타베이스를 가지고 있습니까?

뭐라고 반박하셔도 확신합니다. 코드를 짜고 있다면 설령 혼자 짜더라도 정리된 버그 명세 데이타베이스를 가지고 있지 않다면 낮은 질의 코드로 제품을 출시할 것입니다. 많은 프로그래머들이 머리로 버그들을 모두 기억할 것이라고 생각합니다. 말도 안되는 이야기입니다. 제 경우에는 한번에 2~3개의 버그밖에 기억을 못하고, 다음날이 되거나 출시를 위해 급해지면 전부 잊어버리게 됩니다. 버그를 제대로 트래킹해야합니다.

버그 데이타베이스는 복잡할 수도 있고, 간단할 수도 있습니다. 최소한으로 갖추어야할 요소는 다음과 같습니다:

  • 버그를 완벽하게 재현할 수 있는 과정
  • 버그가 없었다면 이루어졌어야할 결과(동작)
  • 버그로 인하여 생긴 결과(동작)
  • 누가 이 버그에 할당되어 있는지
  • 고쳐진 버그인지 아닌지

버그 데이타베이스를 사용하지 않는 이유가 제품들이 너무 복잡해서라면, 이것들을 포함한 5컬럼의 테이블을 만들어서 사용하기 시작하세요.

버그 트래킹에 관해 더 읽으려면, Painless Bug Tracking을 읽으세요.

5. 새로운 코드를 작성하기 전에 버그들을 잡습니까?

마이크로소프트 Windows용 Word의 첫 버젼은 죽음의 프로젝트였습니다. 끝이 없었습니다. 계속해서 스케줄을 펑크냈습니다. 팀 전체는 말도 안되는 시간동안 일했고, 계속해서 연기되고 또 연기되었습니다. 그 스트레스는 엄청났습니다. 빌어먹을 제품이 몇년 후에 출시되었을때, 마이크로소프트는 팀 전원을 Cancun으로 휴가보내고, 이 원인을 분석하기 시작했습니다.

그들이 깨닫게 된 것은 프로젝트 매니저들이 스케줄을 너무 강요하였기 때문에 프로그래머들은 코딩을 빨리 할 수 밖에 없었습니다. 게다가 버그를 고치는 단계는 스케줄에 아예 존재하지 않았습니다. 결과적으로 질이 아주 나쁜 코드를 만들게 되었습니다. 버그 갯수를 줄이려는 노력은 전혀 하지 않았습니다. 한 프로그래머는 텍스트의 높이를 계산하는 루틴 대신에 "return 12;"로 대체하여 버그 리포트로부터 이 값이 어떤 영향을 주었는지를 알고자 했습니다. 스케줄은 단지 버그일 수 밖에 없는 기능들을 모아 놓은 체크리스트였습니다. 나중에 이 상황을 "무한 결함 방식(infinite defects methodology)"이라고 이름지었습니다.

문제를 해결하기 위해서 마이크로소프트는 반대의 "무결함 방식(zero defects methodology)"라는 방식을 체택했습니다. 많은 프로그래머들은 경영진들의 명령에 의해서 버그 갯수를 줄일 수 있다고 생각했음직한 이 방식의 이름 탓에 이를 비웃었습니다. 하지만 실제로는 "무결함(zero defects)"이라는 이름은 주어진 시간에 가장 우선순위가 높은 것은 코딩하기전에 버그를 잡는 것이란 사실을 지칭하는 말이었습니다. 이유는 다음과 같습니다.

일반적으로 버그를 고치지 않고 방치하는 시간이 길어지면 길어질수록 고치는데 더 많은 시간과 금전이 요구된다는 것입니다.

예를 들면, 오타나 문법오류등은 컴파일러가 쉽게 잡아서 고치는데도 별로 문제가 되지 않습니다.

만일 버그가 처음 실행시에 발생하여 보이게 되면, 모든 코드가 머릿속게 생생하게 존재하기에 바로 고칠 수 있을 것입니다.

며칠전에 작성한 코드에서 버그를 찾게 되면 이를 고치기 위해 조금 시간이 더 걸릴 것입니다. 아마도 코드를 다시 보게 되면 대부분의 내용이 기억나고 적정한 시간내에 버그를 고칠 수 있을 것입니다.

하지만 몇달전에 작성한 코드에서 버그가 발견된다면 이미 그 코드에 관해서 많은 것이 이미 생각나지 않을 것이고, 고치기도 상대적으로 힘들 것입니다. 그때쯤 되면 다른 사람의 코드를 수정하고 있는 와중일지도 모르고, 그사람은 Aruba로 휴가를 떠나있을지도 모릅니다. 이렇게 된다면 버그를 고치는 것은 기술을 익히는 것같이 되어버릴 것입니다. 천천히 꼼꼼하게 그리고 주의 깊게 코드를 살펴봐야 하고, 물론 문제를 해결하는데에 얼마나 걸릴지 정확하게 판단하기 힘든 상황이 될 것입니다.

게다가 이미 출하된 코드에서 버그를 발견한다면, 이를 고치는데에 큰 대가를 치뤄야할지도 모를 것입니다.

이렇게 시간이 적게 들기 때문이라는 이유가 하나의 이유가 됩니다. 또다른 이유는 버그를 수정하는데 걸리는 시간을 예상하는 것보다는 새로운 코드를 작성하는데 걸리는 시간을 예상하기가 훨씬 쉽기 때문입니다. 예를 들면, 내가 당신에게 리스트를 소트하는 코드를 만드는데 얼마나 걸리냐고 물어본다면, 꽤 정확한 대답을 할 수 있을 것입니다. 그렇지만, 질문을 바꿔서 당신의 코드가 Internet Explorer 5.5만 설치되어있으면 동작하지 않는 버그를 고치는데 걸리는 시간을 묻는다면, 문제가 무엇인지도 모르는 상황이기 때문에 얼마나 걸릴지 추측하지도 못할 것입니다. 3일이 걸릴 수도 있을 것이고, 운좋으면 2분이 걸릴 수도 있을 것입니다.

이것이 의미하는 바는 고쳐야할 버그가 많이 존재하는 상태의 스케줄이라면 그 스케줄은 정확할 수가 없다는 것입니다. 그렇지만 이미 알고있는 버그들은 모두 고친 상태라면 그 스케줄은 상대적으로 상당히 정확하게 지킬 수 있는 스케줄일 것입니다.

버그 갯수를 0에 가깝게 하는 또하나의 좋은 점은 경쟁에서 훨씬 빠르게 대응할 수 있다는 것입니다. 어떤 프로그래머들은 이를 두고 제품을 바로 출하할 수 있는 항상 유지하는 것이라고 이야기합니다. 경쟁자가 고객들을 가로채갈만한 굉장히 좋은 기능을 새로 만들었다면 축척된 많은 버그를 수정할 필요없이 바로 이 기능을 추가할 수 있을 것입니다.

6. up-to-date(최신) 스케줄을 가지고 있습니까?

비즈니스에 당신의 코드가 조금이라도 중요한 부분이라면, 코드가 언제쯤 완성될 수 있는지를 아는 것 또한 중요하다는 것은 당연할 것입니다. 프로그래머들은 엉터리 스케줄을 만드는데 악명이 높습니다. "언젠가는 될꺼야!"하고 외칩니다.

불행하게도 그런 식으로는 해결할 수 있는것은 없습니다. 비즈니스에는 코드를 출하하기 전에 데모, 전시회, 광고등등 미리 많은 것들을 판단하여 결정해야합니다. 이를 할 수 있는 단 한가지 방법은 스케줄을 가지고 이를 계속해서 현실적으로 최신내용으로 유지하는 것입니다.

스케줄을 가져야하는 또다른 중요한 이유는 이를 통해서 어떤 기능이 필요한지를 결정하게끔 만들어준다는 것입니다. 때문에 어떤 기능이 덜 중요한지 결정해야하고 featuris 가 되기 전에 이들을 포기하도록 합니다.

스케줄을 관리하는 것이 어려울 필요는 없습니다. 제 글Painless Software Schedules 에 좋은 스케줄을 만드는 간단한 방법을 설명하였습니다.

7. spec(설계서)를 가지고 있습니까?

스펙을 만드는 것은 이빨을 쑤시는것과 같습니다: 모든 사람들이 좋다고 인정하지만, 아무도 하지 않습니다.

왜 그런 현상이 일어나는지는 정확히 모르겠습니다만, 아마도 프로그래머들이 문서를 만드는 것을 굉장히 싫어하는데에 기인하는 것 같습니다. 그 결과로, 프로그래머밖에 없는 집단에서 한가지 문제를 해결하고자 하면, 이들은 문서를 만들기 보다는 코드로 자신들의 의견을 표명하려 합니다. 스펙을 먼저 만들기보다는 차라리 코드를 짜서 보여주는 것을 택한다는 것입니다.

설계 단계에서 문제를 발견하면 몇줄을 고쳐서 이를 수정할 수 있습니다. 그렇지만 코드가 짜여진 상황이라면 이 문제를 수정하는 댓가는 감정적으로나(코드를 그냥 버리는 것을 좋아하는 사람은 없습니다) 시간적으로나 훨씬 높게 되고 더 힘든 작업이 되어버립니다. 스펙을 통해서 만들어지지 않은 소프트웨어는 대개 설계가 잘못되어 스케줄을 엉망으로 만들어놓습니다. Netscape에서도 이런 문제로 인해 브라우저의 초기 네개의 버젼이 너무 엉망이 되어 결국 관리자들이 멍청하게도 코드를 전부 버리고 다시 짜도록한 결정을 내려버리게 되는 상황이 벌어졌습니다. 거기다 한술 더 떠서 Mozilla에서 이런 실수를 다시 반복하여 겨우 Alpha 단계에 가는데 몇년이라는 시간이 걸리게 되었습니다.

필자의 지론은 이 문제는 프로그래머들이 문서를 작성하는데 거부감이 없도록 작문 강의를 듣도록 보내는 것으로 해결할 수 있다는 것입니다. 다른 해결책이라면 스펙같은 문서 작성에 능숙한 관리자를 두는 것입니다. 두 경우 모두 "스펙없는 코드는 금물"이라는 간단한 규칙을 따라야 할 것입니다.

저의 4부짜리 글에 스펙 작성하는 요령에 대해 이야기했습니다.

8. 프로그래머들이 조용한 작업환경을 가지고 있습니까?

지식 근로자에게 공간, 조용함, 프라이버시를 줌으로해서 많은 생산성 향상을 얻는다는 것은 이미 증명된 사실입니다. 소프트웨어 관리의 고전인 Peopleware에서는 이 생산성 향상에 대해 자세히 기술합니다.

문제는 여기에 있습니다. 지식 근로자는 "in the zone"상태라고도 하는 "flow"상태에 들어섬으로써 가장 최상의 상태가 되어 일에 완벽히 집중하고 외부에 개의치 않게 됩니다. 완벽한 집중으로 시간 가는 것을 잊고 좋은 결과를 내게 됩니다. 이때에 바로 대부분의 생산적인 일들을 처리하게 됩니다. 작가, 프로그래머, 과학자 그리고 심지어 농구선수들까지도 "in the zone"상태가 있음을 이야기할 것입니다.

문제는 "zone"으로 들어가는 것이 쉽지 않다는 것입니다. 측정해보면, 최상의 생산성으로 일을 하기 위해서는 평균 15분이 걸립니다. 하지만 어떤 경우에는 피곤하고 이미 많은 일을 한 상태에서 "zone"상태에 들어가지 못하고 다른 일을 하거나 웹서핑이나 테트리스로 시간을 허비하게 될 수도 있습니다.

또다른 문제는 "zone"상태에서 빠져나가는 것이 매우 쉽다는 것입니다. 잡음, 전화소리, 점심식사, 잠시 스타벅스에 5분간 갔다오는 것 그리고 특히 동료에 의한 방해등에 의해 바로 "zone"에서 빠져나가게 됩니다. 동료가 1분이라는 짧은 시간 동안이라도 질문을 하여 "zone"상태에서 빠져나간다면 다시 되돌아가기 위해서 30분이 넘는 시간이 걸려 전체 효율에 치명적인 영향을 미칠 수 있습니다. 카페인 가득한 닷컴 회사들이 좋아하는 합숙소같은 곳에 옆의 마케팅 부서에서 계속해서 오는 전화에 대고 소리지르는 그런 시끄러운 환경이라면 계속된 방해로 지식 근로자들의 생산성은 추락하여 "zone"상태에 절대 이르지 못할 수도 있습니다.

프로그래머들에게 있어서 특히 어렵습니다. 생산성은 단기적인 기억력으로 한번에 얼마나 많은 작은 세부사항들을 다루느냐에 달려있습니다. 어떠한 방해도 이런 세부사항들을 잊어버리게 할 수 있습니다. 일을 다시 재개하면 그것들을 다시 기억하지 못하여 (사용하던 지역변수나 검색 알고리즘을 만들던 중에 어디에서 멈줬었는지등) 다시 찾아보게 되고, 이로 인해 다시 속도가 붙을때까지 느려지게 됩니다.

직관적으로 계산해보면 다음과 같습니다. 만일 프로그래머가 단 1분이라도 방해를 받아서(명백한 근거에 의해) 15분의 생산성을 날려버린다고 합시다. 철수와 영희 두 프로그래머가 낮은 칸막이로 주욱 늘어선(a standard Dilbert veal-fattening farm) 열린 사각 파티션 옆자리에 앉아 있다고 합시다. 영희가 strcpy함수의 유니코드 버젼 이름을 잊었습니다. 30초면 찾아볼 수 있겠지만, 철수한테 물어보면 15초가 걸립니다. 그래서 바로 옆에 앉아 있는 철수에게 묻습니다. 철수는 산만해지고 - 영희의 15초를 아끼기 위해 - 15분을 낭비하게 됩니다.

이번에는 벽과 문으로 나뉘어진 별도의 사무실로 가정을 합시다. 여전히 영희는 함수를 기억하지 못합니다. 다시 찾아보는 것으로 30초를 보낼 수 있을 것이고 옆 방에 있는 철수에게 물어보기 위해서 (일반적인 프로그래머의 평균 물리적인 건강상태를 봐서는 쉽지 않은) 일어나서 걷는 것을 포함한 45초를 보낼 수 있을 것입니다. 결국 찾아보는 것을 선택하여 30초를 보내게 되지만 철수의 15분을 벌어주게 됩니다. 대단하죠!

9. 돈이 허락하는 한도내의 최고의 툴들을 사용하고 있습니까?

컴파일 되는 언어로 코드를 작성하는 것은 여전히 아무 PC에서 할 수 없는 것 중의 하나입니다. 컴파일을 하는데 몇초 이상 걸린다면 최상의 기종을 사용함으로써 시간을 절약할 수 있을 것입니다. 15초 이상 걸린다면 지루해서 그 시간동안 The Onion을 읽게 될 것이고 너무 재미있는 관계로 거기에 빠져 수시간의 생산성을 날려버릴 것입니다.

모니터 하나로 GUI코드를 디버깅한 것은 불가능하지는 않지만 고통스러운 작업입니다. GUI코드를 작성하고 있다면, 2대의 모니터로 훨씬 쉬운 작업을 할 수 있을 것입니다.

대개의 프로그래머들은 아이콘이나 툴바를 위해 비트맵을 수정해야하고 대부분의 프로그래머 역시 좋은 비트맵 에디터를 가지고 있지 않습니다. 마이크로소프트에서 기본적으로 제공하는 Paint 프로그램으로 비트맵을 수정하는 것은 웃긴 일이지만 대부분 이렇게 하고 있습니다.

필자의 가장 최근 직장에서 시스템 관리자가 계속해서 자동적으로 스팸을 보냈습니다. 이유인 즉슨 220MB이상의 하드드라이브를 사용하고 있다는 것이었습니다. 필자는 요즘 HD가격을 본다면 이 공간의 환산된 가격은 내가 이용하는 화장실 휴지보다 싸다는 것을 지적했습니다. 디렉토리를 정리하기 위해 10분을 허비하는 정도로도 큰 생산성 저하일 것입니다.

"최고의 개발팀은 절대 그들의 프로그래머들을 고문하지 않습니다!" 후진 제품으로 인한 작은 불편함이 쌓여서 프로그래머들이 불만에 찰 수도 있습니다. 그리고 그로 인한 불만에 찬 프로그래머는 비생산적인 프로그래머이기 쉬울 것입니다.

이런 것들을 모두 종합하면 프로그래머들은 최고/최신의 것들로 쉽게 매수된다는 뜻이 됩니다. 이는 높은 연봉을 주는 것보다는 훨씬 싼 방법일 것입니다!

10. 테스터들을 고용하고 있습니까?

팀이 최소한 2~3명의 프로그래머에게 테스팅만 전담하는 테스터가 할당되어 있지 않다면, 버그가 많은 제품을 출하하고 있거나 시간당 $100짜리 프로그래머에게 시간당 $30의 일을 시키는 낭비를 하고 있는 것입니다. 테스터를 고용하는 것이 낭비로 생각하는 것은 정말 잘못된 계산을 하고 있는 것이며, 많은 사람들이 이를 깨닫지 못하고 있는데에 놀랍니다.

이에 관해 더 자세히 알고자 한다면 Top Five (Wrong) Reasons You Don't Have Testers 를 읽으십시오.

11. 신입사원들은 면접때 코드를 직접 짜는 실기시험을 봅니까?

마법사를 고용하는데 그의 마법을 보지 않고 고용하시겠습니까? 당연히 그렇지 않겠죠.

결혼식에 요리사를 고용하는데 요리사가 만든 요리의 맛도 모르고 고용하시겠습니까? 그렇지 않을것입니다.(역자주: 실제로 결혼식장 요리사의 맛을 보는 비유는 우리나라에 맞지 않을 것 같네요. 이 문구의 뜻만 이해하세요)

하지만 현실에서는 매일 인상적인 이력서나 면접에서 맘에 든 이유로 고용하는 일들이 일어납니다. 혹은 ("CreateDialog()와 DialogBox()의 차이점은 무엇입니까")등의 문서만 보면 알 수 있는 사소한 질문으로 채용하기도 합니다. 프로그래머를 채용하는데 있어서 중요한 것은 그런 사소한 것들을 얼마나 많이 외웠느냐가 아니고 코드를 잘 작성할 수 있느냐입니다. 혹은 "아하!"류의 질문으로 채용하기도 합니다. "아하!"류의 질문이란 답을 알면 간단하지만 모르는 경우에는 절대 맞출 수 없는 질문을 이야기합니다.

제발 이런 방식을 그만 두십시오. 면접때 무얼해도 상관없지만 반드시 코드를 작성하도록 해야합니다.(더 많은 것을 알고 싶다면 Guerrilla Guide to Interviewing를 읽으십시오)

12. hallway usability testing(무작위 사용성 테스팅)을 하십니까?

무작위 사용성 테스트(hallway usability test)는 복도를 지나가는 다음 사람을 붙잡고 방금 짠 코드를 사용하게 하는 방식입니다. 5명에게 이 테스트를 한다면 95%의 사용성 문제에 대해 배울 수 있을 것입니다.

좋은 사용자 인터페이스 설계는 생각처럼 어려운 것이 아니고 사용자들이 당신의 제품을 구입하고 사용하게 하는데 있어서 절대적으로 중요합니다. 짧은 프로그래머 입문서로 UI 설계에 관해 필자가 쓴 무료 온라인 책을 읽어보실 수 있습니다.

하지만 사용자 인터페이스에서 제일 중요한 것은 많은 사람들에게 당신의 프로그램을 보여주면(5~6명이면 충분합니다) 제일 큰 문제점을 빠른 시간에 발견할 수 있다는 것입니다. Jakob Nielsen의 글에서 그 이유에 대한 설명을 찾을 수 있습니다. UI 설계 경험이 별로 없다고 하더라도 - 비용이 전혀 들지 않는 - 무작위 사용성 테스트를 한다면 당신의 UI는 훨씬 좋아질 것입니다.

Joel Test를 사용하는 4가지 방식

  1. 자신이 속한 소프트웨어 팀의 점수를 매기고 그것에 대해 언급할 수 있도록 결과에 대한 이유를 필자에게 알려주십시오.
  2. 프로그래머 팀의 관리자라면, 당신의 팀이 최대한 잘 운영될 수 있는지 확인할 수 있는 지표로 사용하십시오. 12점을 받기 시작하면 프로그래머들을 간섭없이 그냥 두고 비즈니스쪽 사람들이 그들을 간섭하지 못하게 하는데에 모든 시간을 할 수 있습니다.
  3. 프로그래머 일을 맡을지를 결정해야하는 상황이라면 그 팀의 친한 사람에게 이 테스트 결과가 어떤지를 물어보십시오. 결과 점수가 너무 낮다면 이를 고칠 수 있는 권한을 받을 것인지를 확인하십시오. 그렇지 않으면 불만과 스트레스에 빠질 것입니다.
  4. 프로그래밍 팀을 평가하여야 하는 투자자이거나 당신의 회사가 다른 소프트웨어 회사와 합병을 한다면 이 평가가 급한대로 괜찮은 지표가 될 것입니다.


이 기사는 영어로 The Joel Test: 12 Steps to Better Code 라는 이름의 기사가 원본입니다.
Posted by SB패밀리


프로그래머, 훌륭한 프로그래머란….

과연 내가 성공한 프로그래머라고 말할 수 있는지 내 스스로 확신할 수는 없다. 나는 다만 어떻게 하면 완벽하게 알고리즘을 만들어 프로그래밍을 해야 할지 항상 생각하고 있고, 학교에서 강의를 통해 학생들이 좋은 프로그래머가 되기 위해 어떻게 해야 하는지 계속 훈련시키고 있을 뿐이다.

또 미국의 한 소프트웨어 회사의 연구소를 방학마다 방문해 데이터베이스와 데이터마이닝 등 여러 문제를 놓고 어떻게 하면 아무런 문제없이 쓸 수 있는 소프트웨어를 더 완벽하게 만들 수 있는지를 항상 고민하고 있다.

'그냥 컴퓨터랑 프로그램이 미칠 정도로 좋아서' 거기에 푹 빠져 평생 살아온 것이고, 그래서 전공도 전산학으로 바꿔 소프트웨어의 본고장이라 말할 수 있는 미국에서 공부하고, 미국의 HP, IBM, 루슨트, 마이크로소프트 등 여러 소프트웨어 회사에서 큰 프로젝트를 수행한 경험을 갖고 있을 따름이다.

하지만 가만히 생각해 보니 과연 진정한 프로그래머란 무엇일까라는 질문에 대해 내 나름대로 한번 골똘히 생각해보는 것이 가치있는 일인 것 같고, 또 IT의 강국이라 불리우는 미국에서의 경험이 프로그래머가 되려하는 국내의 많은 이들에게 조금이나마 도움될 것 같아서 내가 그동안 살아온 인생 역정을 간략하게 소개하기로 한다.

부족한 점이 있더라도, 혹은 나와 다른 생각을 가진 독자가 있더라도 너그러이 이해해주길 바란다.

컴퓨터에 푹 빠졌던 그 시절
내가 프로그래밍에 처음 관심을 갖게 된 것은 1983년 여름방학으로 거슬러 올라간다.

당시 국내에서는 퍼스널 컴퓨터에 대한 기술이나 노하우가 전혀 없었던 실정에서 삼성전자와 금성사(지금의 LG전자)는 일본의 NEC에 돈을 주고 PC의 설계를 의뢰해 그 설계대로 PC를 만들어 국내에 판매하고 있었다.

그때만 해도 뭄?컴퓨터는 단지 베이직이라는 언어만을 제공하고 있었다. 또한 청계천의 전자상가에서는 미국 애플 컴퓨터를 불법으로 복제해 팔고 있었고, 애플 컴퓨터의 여러 고급 언어뿐만 아니라 수많은 소프트웨어가 불법으로 국내에 유통되고 있었다.

당시에는 국내 기업들이 PC를 사거나 약간의 수강료를 낼 경우 자사의 컴퓨터를 쓸 수 있도록 1주일 정도 간단하게 베이직 언어 등을 가르쳐줬다. 나도 그때 컴퓨터가 무엇인지 알기 위해 수강료를 내고 1주일 동안 금성사의 퍼스널 컴퓨터를 배웠다.

나에게 있어서 PC는 너무나 신기한 것이었다. 음악을 연주할 수 있고, 그림을 그릴 수도 있고, 또 간단한 수학적인 것들을 계산해 볼 수도 있고, 주어진 숫자들을 정렬할 수도 있었다. 이러한 것들은 대학 2학년생이던 나를 너무나 매료시켰다. 일주일 동안 배운 내용으로는 부족한 것이 많아 동화서적에서 나에게 컴퓨터를 가르쳐준 강사를 계속 찾아가 궁금한 것을 물어 보며 배우기 시작했다.

하나씩 알아가는 기쁨이 있었던 PC
그때는 정말 밤새도록 프로그래밍을 하면서 내가 원하는 것이 PC로 수행되는 것을 볼 땐 정말 즐거웠다. 국내에 PC에 대한 서적이 거의 없는 현실에서 이것저것 베이직 인터프리터의 내용을 분석해 하나씩 알게 될 때마다 그 기쁨은 이루말할 수 없었다.

사실 베이직 인터프리터라는 것이 기계어로 돼 있어 C++와 같은 고급언어로 돼 있는 프로그램과 달리, 눈으로 보고 이해하기는 많은 어려움이 있었다. 그래서 인터프리터의 기계어를 역 어셈블해 하나하나 분석한 후에 이해할 수 있었을 때는 정말 뛸 듯이 기뻤다. 또 청계천의 서점에서 일본책들을 구해, 비록 국내 PC와 호환성은 없는 내용이지만 바꿔서 국내 퍼스널 컴퓨터에서 돌아가게 했을 때, 그 기쁨은 말할 수 없었다.

어렵게 알아낸 만큼, 알아낸 내용을 값지게 활용하고픈 욕심은 어쩌면 당연한 것이었다. 국내에서 주최하는 각종 PC 경진대회에 출전해 여러번의 입상 기회를 가질 수 있었다. 1985년 대우전자에서 주관하는 소프트웨어 공모전에서 금상을, 과기처주관 소프트웨어 경진대회의 경시부문과 공모부문에서 문교부 장관상과 상공부장관상을 각각 수상했다.

또한 1985년부터 1987년에 걸쳐 마소에 'MSX의 모든 것'을 시작으로 여러 편의 글을 기고하기도 했다. 당시에 MSX는 여러 회사의 PC 소프트웨어들의 호환성을 보장하기 위해 제안된 표준사양이었다. 그때엔 이처럼 하나하나 분석해 알아낸 것들을 국내에 알려주는 일 역시 큰 기쁨 중에 하나였다.

프로그래머 인생의 새로운 출발, 미국으로의 유학길
이렇게 퍼스널 컴퓨터와 씨름하면 할수록 궁금증은 더해만 갔다. 예를 들어 정렬 알고리즘들이 왜 여러 가지가 존재하는지 나는 사실 이해할 수 없었다. 단지 책에 나와 있는 내용을 그대로 베껴 수행시켜보면 알고리즘에 따라 수행속도가 무척 다르다는 점만 알고 있었다.

하지만 내가 사서 봤던 일본 서적들은 단지 라이브러리처럼 소스 코드를 보여주기만 할 뿐, 왜 같은 데이터로 다른 수행속도를 보이는지에 대해서는 전혀 설명하지 않았다.

나의 이러한 호기심은 전산학 과목을 들으면서 조금씩 해소되기 시작했다. 자료구조론, OS, 컴파일러, 시스템 프로그래밍 등의 강의는 나의 궁금증을 조금씩 해소시켜줬다. 하지만 국내에 전산학을 제대로 전공한 사람들이 당시에는 별로 없었으며, 시대적 여건 또한 힘든 상황이었기 때문에, 나는 미국에 유학가기로 마음을 먹었다. 유학을 가기로 마음을 정한 후에는 정말 열심히 공부했다.

하지만 웬만한 부자가 아니라면 유학은 꿈도 못꿀 일이었다. 가난했던 내가 유학을 가기 위해서는 미국의 학교에서 재정적인 보조를 받아야만 했기 때문에, 좋은 학점을 받아야만 했고, 그래서 열심히 공부했다.

본격적으로 전산학 교육을 받으면서
마침내 졸업할 땐 내가 공부했던 전기공학과에서 수석으로 졸업할 수 있었고, 미국에서 전산학 분야로 이름난 학교 중 하나인 University of Maryland at College Park의 전산학과 대학원에서 학비 전액 면제와 생활비 보조를 받으며 공부할 수 있는 기회를 얻었다. 전산학과를 졸업하지 않았어도, 다른 학부 전공에서 우수한 성적을 얻은 만큼, 전산학을 하더라도 잘할 거라고 믿어주는 교육 시스템은 기꺼이 나를 받아준 것이다.

나는 사람들에게 기회를 주는 미국의 시스템을 존경한다. 내가 전산학을 할 수 있었던 것도 사실은 유학을 갔기 때문에 가능했던 것 같다. 당신 국내 대학원에 진학하려면 전산학 관련 과목의 시험을 봐야했고, 또 해당 학과를 나오지 않으면 대학원 진학이 무척 힘들던 시절이었다. 하지만 미국 대학들은 그런 점에 상관하지 않고 나에게 기회를 줬고, 프로그래머로서의 내 인생은 달라졌다.

대학 1학년 때 지하철을 타고 가다 리더스 다이제스트 잡지에서 읽었던 한 구절의 글이 인상깊은 기억으로 남아있다. "항구에 정박해 있는 배는 안전하다. 그러나 배는 항구에 묶어두기 위해 만든 것이 아니다". 그 글을 본 순간 나는 너무나 벅찬 감동을 받았다.

돌이켜 생각해 보면 그 글은 내가 인생을 살면서 여러 갈래의 길에 서게 될 때마다 어려운 길일지라도 항상 도전할 수 있는 힘과 용기를 갖게 해줬다. 아마 내가 어려운 가정 형편이지만 미국으로 유학을 가려고 시도했던 것도 바로 그 글 때문이 아니었을지….

창의력 기르기 위한 끊임없는 훈련 돌입
미국의 대학원에서 전산학을 공부하며 제일 먼저 놀란 점은 아무도 프로그래밍이나 숙제를 남의 것을 베끼지 않고, 누구나 스스로 한다는 것이었다.

또한 우리 나라의 주입식 교육 방식과 달리 창의력을 길러주기 위한 방향으로 교수가 가르친다는 점이었다. 예를 들어 전산과에 1학년으로 들어오면 그 당시에는 파스칼이라는 언어를 가르치는데, 프로그래밍을 할 때 쓸 수 있는 타입은 캐릭터만을 주고 정수(integer)나 실수(float) 타입은 전혀 쓸 수 없게 해서 프로젝트를 코딩하게 한다.

이렇게 하면 "I := I+1"과 같은 문장 하나를 수행시키려 해도, "0" 이면 "1"로 바꾸고 "1"이면 "2"로 바꾸는 한 자리 숫자에 1을 더하는 프로시쥬어를 먼저 만들어야 한다. 그 다음에 그, 프로시쥬어를 이용해 여러 자리의 수에 1을 더하는 프로시쥬어를 만들고 사용해야만 한다.

물론 이렇게 코딩하려면 기존의 언어에서 간단하게 할 수 있는 프로그램도 사이즈가 길어지고 아주 많은 잡일이 필요해진다. 하지만 쓸 수 있는 언어의 모든 기능을 허용하지 않음으로써, 학생들은 많은 생각을 해야만 하고 그렇게 해서 창의력이 길러지는 것이다.

또한 1부터 10까지 더하는 프로그램이 있을 경우, 그 프로그램이 정말로 그 합을 구한다는 것을 증명하는 방법을 학생들에게 가르쳤다. 당시 미국으로 공부하러 갈 때까지 프로그램을 증명 한다는 말은 들어보지도 못한 때였다.

또 자료구조라는 과목을 미국에서 들었는데 학기말 프로젝트가 LISP라는 언어의 인터프리터를 만드는 것이었다. 당시에 상용화 돼 팔리고 있던 소프트웨어를 학기말 프로젝트로 한다는 게 과연 가능할까 생각했지만, 그 과목을 공부하는 동안 그런 능력을 갖출 수 있도록 스케쥴대로 우리들은 훈련되고 있었다.

LISP라는 언어는 리스트, 스택, 해싱 등 자료구조 과목에서 배우는 모든 것을 실제로 사용해야만 완성할 수 있는 것이라서, 그 과목에서 배운 내용을 실제 사용할 수 있게끔 만드는 경험을 얻을 수 있도록 나를 훈련시켜줬다.

처음부터, 학부 과정부터, 다시 시작하는 마음으로
단지 생각나는 대로 주먹구구식으로 프로그래밍을 하던 나에겐 너무나 충격적이고 익숙하지 못한 시스템이었기에 처음에는 공부하기가 너무나 힘들었다. 시험 문제도 족보에서 나오지 않았으며, 암기해서 쓸 수 있는 문제 또한 시험에 전혀 나오지 않았다.

10년 된 강의 노트를 그대로 사용하지도 않았고, 숙제조차도 교수가 일일이 매번 새로 문제를 만들어 나눠주기 때문에, 항상 많은 시간 생각을 해야만 풀 수 있었던 문제들…. 그것들을 통해 나는 아주 느리지만 조금씩 창의력을 키워나갈 수 있었던 것 같다.

나는 그때까지 내가 배워왔던 모든 것을 떨쳐버리고 처음부터 시작한다는 마음을 먹기로 했다. 한국에서 '일류대'라 부르는 학부를 졸업했고, 과 수석을 했다는 사실은 모두 던져버리고 겸손해져야 제대로 배울 수 있다는 생각으로, 전산과 학부 과목부터 하나씩 들었다.

그로 인해 석사나 박사를 받는 시기가 늦어지긴 했지만, 어떻게 보면 오히려 학부 과목부터 하나씩 공부하고 기초부터 튼튼하게 키움으로써, 나중에 더 만족할만한 논문을 쓸 수 있지 않았나 싶다.

우리 나라에서 종종 20대 박사라는 둥, 박사과정을 몇 년만에 마쳤다는 둥 그런 이야기를 신문이나 잡지에 내세우고, 또 자부심을 갖는 걸 보면 참 한심하다는 생각이 든다. 미국에서는 그런 걸 별로 중요하지 않게 생각한다. 오히려 중요한 것은 얼마나 좋은 논문을 썼는가, 얼마나 세상에 영향을 끼칠 수 있는 것을 연구해 개발했는가를 더 중요하게 생각한다.

또 박사학위를 받은 후에 좋은 곳에 일자리를 얻기 위해 졸업을 할 수 있지만 일부러 졸업을 미루면서 더 좋은 논문을 많이 쓰려고 하는 경우도 많이 볼 수 있다. 사실 무조건 학위를 받는 것이 중요하다면 얼마든지 쉬운 논문 주제를 찾아 쉽게 졸업할 수도 있다. 하지만 단지 박사 학위만을 받는 것이 과연 무슨 의미가 있을까.

왜 데이터베이스인가, Because it is there!
나는 1988년에 컴퓨터 그래픽 분야로 석사논문을 썼고, 국내에 병역문제로 들어왔다가 다시 들어가서 1990년 여름부터 박사과정을 계속했다. 나는 여러 분야 중에서 데이터베이스 분야를 박사 논문주제로 연구하기로 했다. 관계형 데이터베이스 시스템(Relational Database System)에서는 SQL이라는 언어를 가지고 질의(Query)를 표현하는데, 이 언어에서는 데이터 중에서 무엇을 원하는지를 나타내면, 데이터베이스 시스템의 질의 수행에 있어 가장 최적의 수행 방법을 찾아 수행시켜준다.

이때 최적인 방법을 찾는 문제는 아주 복잡한 문제로(전산 용어로 NP-Hard의 클래스에 들어가는 문제임) 질의의 최적화(Query Optimization)라 불리운다. 이 최적화가 효율적으로 기능을 발휘할 때 비로소 데이터베이스 시스템이 초보자에게도 효과적으로 사용될 수 있다. 논문을 준비하던 당시에는 객체 지향형 모델(Object-Oriented Model)을 관계형 데이터베이스 시스템(Relational Database System)에 접목하려던 시점이었기 때문에 새로운 여러 질의 최적화 문제를 해결해야만 할 때였다.

질의 최적화의 문제들은 새로운 알고리즘을 만드는 것이었고, 프로그래밍을 즐겼던 나에게는 너무나 재미있는 문제들이었기 때문에 데이터베이스의 질의 최적화 는 나의 관심을 사로잡을 수 있었다.

이쯤에서 George Mallory라는 영국 탐험가 이야기를 꺼내려 한다. 그는 에베레스트 산의 등정을 최초로 여러 번 시도하다가 사고로 죽었는데 아직도 그가 에베레스트 산의 정상에 올라간 후에 죽었는지 아니면 오르지 못하고 죽었는지는 미스테리로 남아있는 부분이다. 그러한 그가 죽기 전에 많은 사람들이 그에게 왜 위험한데도 에베레스트 산을 자꾸 오르려 하냐고 질문했다. 그때 그는 이렇게 대답했다고 한다. "Because it is there."

만일 나에게 누가 왜 데이터베이스를 연구하게 됐는지 물어본다면 나도 그렇게 말하고 싶다. "엄청난 양의 데이터가 언제나 바로 내 옆에 있었기 때문이다"라고. 이젠 인터넷 전체가 커다란 데이터베이스나 다름없다. 간단한 컴퓨터와 인터넷만 있으면 나에게 필요한 모든 데이터를 쉽게 접근할 수 있는 시대가 돼버린 것이다.

완벽한 소프트웨어를 만든다는 것
박사 과정 중에는 데이터베이스의 최첨단 연구소 중 하나인 HP 연구소에서 Surajit Chaudhuri 박사의 섬머 인턴 학생으로 1992년과 1993년 여름에 공동으로 연구했고, 여러 편의 논문을 데이터베이스 분야에서 권위있는 여러 데이터베이스 학술회의에서 발표했다.

미국 실리콘밸리의 벤처 1호 회사라고 알려진 이 회사는 스탠포드 대학을 졸업한 윌리엄 R. 휴렛과 데이빗 패커드가 1939년 공동으로 차고에서 시작했다. 그들이 처음 만들어 판매한 제품은 오디오 오실레이터로 월트 디즈니사에 처음으로 납품했고, 그때 사용된 차고는 지금 미국 캘리포니아 주의 역사적인 사적지로 지정돼 있다.

이 회사의 연구소에서 느꼈던 것은 프로그래머들이 그냥 무조건 코딩을 하는 것이 아니란 점이다.

오랫동안 수많은 연구와 생각을 거듭해 자신이 디자인한 알고리즘이 전혀, 조금이라도 문제가 없다고 생각될 때라야 코딩을 한다. 그냥 일단 별 생각없이 코딩부터 시작하는 나의 초창기 프로그래머로서의 모습과는 너무나 대조적인 스타일이었다. 하지만 그것이 얼마나 중요한 일인지는 그 뒤로 명성있는 미국 소프트웨어 회사들에서 일하며 몸소 깨닫게 됐다.

코딩을 위한 기초 공사 튼튼히 해야
사실 보통 사람들은 프로그래밍을 하는데 주먹구구식으로 그냥 코딩부터 하는 경우가 많다. 하지만 강조하고 싶은 것은 훌륭한 프로그래머가 되려면, 우선 깊이 생각해서 알고리즘을 디자인한 후에 정말로 우리에게 주어진 문제를 완벽하게 수행해준다는 것을 증명하고, 수행 속도라든가 필요한 메모리의 양을 분석해야 한다는 것이다.

그런 다음에 정말로 코딩을 해서 실제 데이터를 갖고 알고리즘을 수행시켰을 경우 완벽하게 해낼 수 있는 완전한 시스템을 만들 수 있으리라는 확신이 섰을 때에 비로소 코딩해야 한다.

프로그래머가 되려는 사람 중에는 이러한 분석이나 디자인을 위해 필요한 기초인 자료구조, 오토메타 이론, 알고리즘, 데이터베이스, OS 등의 내용을 배우려하는 것을 등한시하면서도 프로그래머가 될 수 있다고 생각하는 이가 있다.

다시 한번 강조하지만 건물이나 다리를 짓는 데에 있어서도 지진이나 그밖에 다른 이유로 무너지지 않게 하려면 아주 정확한 계산에 의한 설계와 기초 공사가 아주 중요하다. 마찬가지로 완벽한 소프트웨어를 만들려면 그러한 것을 코딩하기 위한 기초가 되는 내용들을 열심히 공부해 튼튼히 쌓아야만 가능하다는 것이다.

IBM Almaden 연구소에서 데이터마이닝 연구
박사학위를 받은 뒤에는 우리 나라의 경제기획원에 해당하는 미국의 Federal Reserve Board의 리서치 부문에서 약 1년간 연구했다. 그때 놀란 것은, 그들이 전세계 수많은 나라의 경제에 관련된 데이터를 계속 모으고 있으며 그것을 이용해 세계 경제의 흐름을 이해하려 하고 또 자국의 이익을 위해 사용한다는 것이었다. 그렇기 때문에 우리 나라에 몇 년전에 발생했던 IMF도 미국이 먼저 알았다는 말이 나온 게 아닐까 생각한다.

내 생각엔 미국의 힘은 그들이 계속 모아오고 있는 수많은 데이터인 것 같다. 지금도 계속 우주에서 보내오는 우주 사진들을 후세를 위해 미국은 계속 그냥 모아놓고 있다.

어떻게 보면 지금 바로 쓸 수도 없는 그 많은 양의 데이터를 계속 수집하고 있는 것이 무슨 소용이 있나라고 의아해하고 있는 사람들도 있을 것이다. 하지만 사실 나중에 그 데이터들을 사용할 수 있는 기술들이 개발될 때를 위해 지금의 데이터를 수집하고 있는 미국의 개척자적인 모습은 역사가 짧을지라도 세계적으로 앞서가는 나라를 만들 수 있었던 저력이라 생각한다.

내가 Federal Reserve Board에서 일하는 동안 소프트웨어분야의 최첨단 연구소 중 하나인 IBM Almaden 리서치 센터의 Rakesh Agrawal 박사가 막 시작하려던 퀘스트 데이터마이닝 프로젝트에 참여를 제안 받았다. 그 당시에는 미국의 여러 기업이 상업용 데이터베이스 소프트웨어를 이용해 자사의 소비자들에 대한 정보를 모두다 컴퓨터에 보관하고 있었다.

하지만 마케팅이나 CRM(Customer Relationship Management) 등에 그 데이터를 어떻게 이용해야 할지 전혀 모르고 있던 시절이었고, 그렇기 때문에 이 데이터에서 유용한 정보를 찾아내려는 데이터마이닝이라는 분야가 처음 태동되는 시기였다.

내가 대학원에서 전공한 분야와 다른 새로운 분야를 시작한다는 것이 조금은 주저가 되었지만 새로운 분야를 개척해보고 싶은 열망과 훌륭한 연구소 중 하나인 IBM Almaden 리서치 센터에서 일하고 싶어 흔쾌히 제안을 받아들였다. 그 후로 1994년부터 1996년까지 Rakesh Agrawal 박사와 열심히 데이터마이닝 분야에 대해 연구했다.

내가 그때 연구하고 코딩한 것들 중에는 IBM에서 상용화해 현재 팔고 있는 데이터마이닝 소프트웨어인 IBM Intelligent Miner의 주요 엔진의 일부로 현재 많은 사람들이 사용하고 있다.

그곳에서 본 프로그래머의 모습
나는 이 프로젝트의 초기에 참가해 최첨단의 새로운 분야의 연구를 주도하는 자세와 방법, 그리고 실제 상업용 시스템 소프트웨어를 개발하는 값진 경험을 습득할 수 있었다. 우선 이들은 계속 공부한다는 점이다.

가까운 대학에 나가 계속 새로운 지식을 배우고, 또 자기가 참여하고 있는 프로젝트에 관련된 유명한 사람들을 불러 계속 세미나를 듣고 또 회사에서 그러한 일에 투자하는 것을 아깝게 여기지 않았다. 왜냐하면 나중에 그들이 프로그래밍을 프로젝트를 위해 일할 때에 다 쓰일 것이기 때문이다. 또한 그들은 누구나 코딩을 잘한다.

한국에 돌아와 국내 연구소에서 일하는 사람들로부터 종종 듣는 얘기가 있다. "나는 코딩 같은 것은 안한다"고. 우리 나라 연구소에서는 코딩을 하면 마치 수준이 낮은 것처럼 평가받는 듯하다.

하지만 세계적으로 유명한 소프트웨어 회사의 명망 있는 연구원들은 누구나 코딩을 잘 한다. 코딩을 하지 않으면 실제 소프트웨어를 디자인할 때 병목현상이 어디서 발생하는지, 실제 소프트웨어가 돌아가는 데 있어 어떤 것을 해결해야 하는지를 잘 알 수 없다. 그렇기 때문에 좋은 논문을 쓸 수 없고 소프트웨어를 만든 후에 생각지도 못한 일들이 생겨 수년동안 애써 일한 것이 모두 수포로 돌아가는 경우가 많다.

IBM이나 마이크로소프트를 비롯한 소프트웨어 회사 연구소의 연구원들은 프로그래밍에 있어서도 세계 최고 수준이다. 또한 디버깅을 위해 사용할 수 있는 여러 가지 툴을 아주 적절히 사용할 수 있는 능력을 갖추고 있어, 빠른 시간 안에 프로그래밍을 할 수 있는 능력을 갖고 있다.

세상 사람들에게 널리 유용하리라고 생각하고 연구해 개발하고 디자인한 알고리즘들을 회사에서 상용화하도록 밀고 나가려면 우선, 프로토 타입도 스스로 만들어 데모도 하고 그 가능성을 또한 보여줘야하기 때문이다. 그렇기 때문에 나는 교수이지만 아직도 많은 경우에 스스로 코딩을 할 때가 많다. 그리고 코딩을 직접 할 때마다 대학생 시절 프로그래밍에 빠져들었던 때의 열정을 다시 조금이나마 경험하곤 한다.

벨 연구소에서 Serendip 데이터마이닝 프로젝트를 시작
나는 IBM Almaden 연구소에서 경력을 쌓고 있는 동안 전산 분야의 세계적인 연구소인 벨(Bell) 연구소로부터 데이터마이닝 프로젝트를 새로 시작해보지 않겠냐는 제안을 받았다. 벨 연구소는 수많은 노벨상 수상자를 배출한 곳으로서, 현재 모든 전자제품의 반도체에 사용되는 트랜지스터를 최초로 개발한 곳이다. 또한 지금 보편화돼 사용하고 있는 레이저를 개발한 아주 명성 높은 연구소다.

IBM에서 Rakesh Agrawal이라는 대가의 지도를 받으며 연구하는 것도 좋았지만, 언젠가는 내 스스로 큰 프로젝트를 주도해 수행하려면 경험을 쌓아야 하므로 그 제안을 흔쾌히 받아들였다. 그리하여 1996년 3월 Bell 연구소로 옮겨, 그곳에서 Serendip 데이터마이닝 프로젝트를 Rajeev Rastogi 박사와 함께 시작해 많은 공동연구를 했다.

옛날에 페르시아에 'Serendip'이라는 조그만 나라가 있었는데 그 나라의 왕자들은 어디를 가든지 생각지도 않았던 아주 소중하고 값진 것들을 발견하는 재주가 있었다고 한다. 여기서 유래된 Serendip이라는 단어는 Serendipity의 어원으로써 '생각하지도 않았던 값진 것을 우연히 찾는 것'을 뜻한다. 그렇기 때문에 내가 Bell 연구소에서 시작한 데이터마이닝 연구의 프로젝트 이름으로 이 단어를 사용했다.

약 4년 동안, 나는 KAIST에 조교수로 부임하기까지 다수의 논문을 명성있는 국제 학술회의에 발표했으며, 또한 국제 저널에 다수의 논문을 게재했다. 나는 이 프로젝트의 리더로서 연구를 성공적으로 수행함으로써 데이터마이닝 분야에서 나의 공헌을 인정받는 계기를 얻었다. 이 프로젝트에서 개발된 수많은 연구는 현재 미국 특허를 이미 받았거나 신청 중에 있다.

나는 또 벨 연구소에 있는 동안 매년 섬머 인턴으로 미국의 대학에서 여러 학생들을 받아 지도해 내 분야의 최고 국제 학술회의에 논문을 실을 수 있도록 했다. 돌이켜 보면 나는 벨 연구소의 경험을 통해 새로운 최첨단 분야의 프로젝트를 스스로 제안하고 개척해 리더로서 성공하도록 수행하는 방법을 터득했다.

우리 나라에 돌아와서
미국에서 성공적으로 해당 분야에서 명성을 쌓고 있는 동안에 항상 마음 한구석에는 내가 40대가 되기 전에 적어도 몇 년만이라도 나의 조국을 위해 일해야 한다는 생각에 종종 잠기곤 했다. 하지만 그 결정이 쉽지는 않았다. 왜냐하면 프로그래머에게 환경이 아주 잘 정착돼 있는 미국에서 일하는 것이 너무나 효율적이고 편하기 때문이다.

하지만 언젠가 '이집트의 왕자'라는 디즈니의 만화영화를 영화관에 가서 아이들과 함께 보다가 이집트에서 최고의 교육을 받고 이집트의 왕자가 됐지만, 자기 민족을 위해 이집트 왕자로서의 모든 부귀와 영화를 버리고 과감히 이집트를 떠난 그의 마음을 이해할 수 있었다. 그 이후로 국내에 돌아오기로 결정하고 KAIST에 부임했다.

KAIST에서 강의하는 일과 함께 전자상거래와 인터넷 검색 엔진, 그리고 인터넷 보안에 관련된 연구도 데이터마이닝과 함께 열심히 연구하고 있다. 특히 전자상거래와 인터넷에서 차세대에 주로 사용될 예정인 XML 형태의 효율적인 처리에 관해 미국 마이크로소프트 연구소와 공동으로 연구를 활발히 진행하고 있고, 또 벨 연구소와도 계속 데이터마이닝에 관해 연구하고 있다. 지난 겨울에도 미국의 시에틀에 위치한 마이크로소프트 연구소에 방문 과학자로 초대돼, 마이크로소프트의 XML 관련 인터넷 소프트웨어의 효율성을 위해 열심히 연구했다.

간단히 논문 한편 쓰는 것과 실제 사람들에게 사용될 수 있는 완벽한 소프트웨어를 만들기 위하여 연구하는 것은 큰 차이가 있다. 실제 소프트웨어를 코딩하기 전에 아무런 문제가 없다는 것을 완벽하게 증명해야 하고 이것저것 고려할 것도 많기 때문이다.

그렇기 때문에 더욱더 어렵고 힘든 일이지만 또 그렇기 때문에 가치 있는 일이라 생각한다.

세계 소프트웨어 시장으로 진출하기 위해
우리 나라에 돌아온 뒤에는 국내 산업에도 기여하고 싶어 와이즈엔진(www.wisengine,com), 엠브레인(www.embrain.co.kr), 그리고 에어마인(www.airminesoft,com) 등의 국내 벤처 회사들에 데이터마이닝과 인터넷 관련 소프트웨어 기술에 대한 자문을 해주고 있다. 우리 나라도 미국처럼 한 사람이 수천 명을 먹여살릴 수 있는 그런 소프트웨어 회사들이 나올 수 있기를 기대한다. 그러기 위해 강조하고 싶은 것이 있다면 우리도 우리 기술을 가져야 한다는 것이다.

또한 나는 교육의 중요성도 새로이 인식하고 학생들의 전산학과목도 열심히 성심을 다해 강의하려 한다. 특히 학생들을 세계적인 수준으로 만들기 위해서는 영어의 필요성을 너무나 깊이 인식하고 있고 또 국제화시키기 위한 일환으로 KAIST에서 내가 강의하고 있는 모든 과목을 영어로만 진행하며, 시험이나, 숙제, 그리고 프로젝트 모두 영어로 내주고 있다. 영어 역시 훌륭한 프로그래머가 되기 위해 갖춰야할 것 중 하나라고 강조하고 싶다.

전산학 분야에서 앞서가고 있는 선진국을 따라 잡으려면 영어를 잘해서 그들이 만들어 놓은 논문이나 책을 빨리 이해하고 우리 것으로 만들 수 있어야 하기 때문이다.

또한 우리가 어떤 소프트웨어를 만들든지 작은 국내 시장에서 안주하지 말고 세계 시장으로 나가야 할 것이다. 그러기 위해서는 영어가 아주 중요한 역할을 한다고 생각한다.

우리는 그들에게서 무엇을 배워야 하나
전산학 분야는 노벨상이 없지만 그 대신 튜링상(Turing Award)이라는 것이 있다. 내가 말하고 싶은 건 이 상을 받았던 역대 수상자들은 논문 개수로 받은 것이 아니라 별로 많지 않은 논문일지라도 그 연구 결과가 이 세상에 끼친 영향이 너무나 크기 때문에 받았다는 사실이다. 국내 최고니 아시아에서 최고니 그런 건 별 의미가 없다. 세계 최고의 기술력을 확보할 수 없다면 경쟁력을 갖출 수 없기 때문이다.

현재 내가 몸담고 있는 KAIST뿐만 아니라 국내의 다른 대학들도 세계적인 대학으로 발돋음할 수 있기를 진정 바라고 있다. 그러기 위해서는 교수와 학생에 대한 대우나 평가도 세계적인 명문대학 수준으로 해줘야 한다고 생각한다.

그러지 않고 어떻게 세계적인 수준으로 우리들이 갈 수 있겠는가. 또 그렇게 되지 않고 어떻게 선진국의 소프트웨어 회사들과 경쟁할 수 있겠는가. 같은 환경이라도 우리는 뒤늦게 출발해 더 어려운 상황이니 말이다.

지금 많은 학생이 유학을 떠나고 있고, 또 많은 학생들이 학부나 석사과정만 마치고 더 이상 박사학위에 지원하지 않고 있다. 그렇기 때문에 국내 대학에서 일하는 나와 같은 교수들은 같이 연구할 학생들이 없어 더욱 어려움에 처하고 있다.

하지만 어쩌면 국내 대학이 학생들에 대한 자세를 선진국의 명문 대학처럼 바꾸려고 노력할 수 있는 계기가 될 수 있을 것 같아 한편으로는 기쁘다. 왜냐하면 대학의 주인은 교수나 교직원이 아니라 바로 학생들이기 때문이다. 우리 나라의 대학들이 이것을 인식하지 못하고 구태의연하게 있는 동안 학생들이 점점 빠져나갔기 때문이다.

나는 또한 공부를 중단하고 벤처 회사로 나가는 학생들에게 한 가지 당부하고 싶은 게 있다. 선진국의 소프트웨어의 벤처 회사에서 일하는 많은 이들은 전산학 공부를 대학원 과정을 통해 열심히 훈련을 받은 후에 자기만의 기술을 독자적으로 개발했기 때문에 가능한 것이지, 탄탄한 기초와 자기만의 기술이 없이 그냥 아무렇게나 시작한 것이 아니라는 것이다.

또한 자신이 개발한 소프트웨어는 모두 특허를 신청해 자사의 지적 재산권을 보호하고 있다. 이러한 것들을 우리 나라의 프로그래머들도 배워야하지 않을까.


하나에만 몰두하는 바보가 되라
내가 미국에서 공부하면서, 그리고 미국의 많은 소프트웨어 회사의 연구소에서 일하면서 느낀 점은 미국의 학생들은 정말로 전공하는 학문을 좋아하기 때문에 대학에 오고 또 대학원에 진학한다는 사실이다. 그렇기 때문에 정말로 열심히 열정적으로 한 가지만 공부하고 연구한다. 영화 '포레스트 검프'에 나오는 주인공처럼 한 가지만 몰두해서 바보처럼 일할 때 우리는 그 분야의 전문가가 될 수 있다. 또 그렇게 할 때 정말 뭔가를 이뤄낼 수 있다는 생각이 든다.

만일 어떻게 하면 성공한 프로그래머가 될 수 있냐고 나에게 묻는다면 난 이렇게 말하고 싶다. 정말로 프로그래밍이 미칠 정도로 좋으냐고. 컴퓨터만 보면 미친 사람처럼 좋은지, 프로그래밍을 하면 정말로 즐거운지 묻고 싶다. 만일 여러분이 그렇다면 프로그래머로서 성공할 수 있는 가능성을 충분히 갖췄다고 생각한다. 그 다음은 앞서 말한 기본적인 기초 과목을 공부해 기반을 튼튼히 다져서 어떤 것을 코딩하든지 완벽하게 하려는 열정을 갖도록 하라. 그리고 나이에 상관하지 말고 계속 공부하라.

미국의 대학에 있다보면 30대에서 60대까지 다양한 연령층이 대학에 와서 대학생들과 함께 전산학 강의를 듣는 것을 볼 수 있다. 그렇게 계속 공부하지 않으면 프로그래밍에 관해서 새로 개발된 좋은 언어나 알고리즘을 이용할 수 없어 코딩한 프로그램이 비효율적일 가능성이 높다. 전산학 자체가 물리나 화학과 같은 분야처럼 고전적인 학문이 아니고 지금도 계속 새로운 내용들이 아주 빠르게 개발되고 변화하는 분야이기 때문에 계속 공부를 해야 한다는 사실을 강조하고 싶다.

또한 팀웍의 중요성을 말하고 싶다. 하나의 프로젝트를 수행하려면 여러 사람이 한 팀을 이뤄서 서로 다른 부분을 프로그래밍해야 한다. 그러려면 그 프로젝트를 성공시키겠다는 목표를 향해 자신을 희생할 줄도 알아야 한다. 안되면 밤을 새워서라도 반드시 계획대로 만들어 내려는 그런 의지를 갖고 서로 협조해 일하는 자세가 필요하다.

미국의 훌륭한 소프트웨어 회사에서 일하는 사람들에게서 느낄 수 있었던 것 중의 하나가 바로 이점이었다. 또 소프트웨어 분야 선진국의 발전된 모습이 필요할 때면 언제든지 이해하고 우리에게 적용할 수 있도록 영어를 잘하도록 갖추라고 말하고 싶다.

그래야 세계 시장에서 팔릴 수 있는 소프트웨어를 만들어 우리 나라 산업의 발전에 기여할 수 있기 때문이다. 앞서 언급한 사실들을 명심하고 준비한다면 반드시 훌륭한 프로그래머로 성공할 수 있으리라 생각한다.

컴퓨터가 좋아서, 프로그래밍이 좋아서
이 글을 맺으면서 하고 싶은 말이 있다면, 'Life is full of Serendipity'라는 말이다. 우리글로 표현한다면 '인생이란, 아주 먼 옛날에 신이 나를 위해 미리 준비해놓은 소중하고 값진 것들을 하나씩 찾아가는 기쁨'이라는 의미로, 내가 만들어낸 말이다. 이 말은 짧은 인생이지만 그동안 살아오면서 인생에 대해 내가 느낀 것을 아주 함축적으로 잘 나타내 주는 말이다. Serendipity라는 단어를 나는 무척 좋아한다.

앞서 얘기했듯이, 벨 연구소에서 수행한 데이터마이닝 프로젝트의 이름으로 사용한 Serendip이라는 어원에서 나온 단어이기도 해서 그런지도 모르겠다.

마소에 처음 기사를 썼던 1985년에는, 그 후로부터 지금까지 내가 살아온 경험들을 전혀 상상하지 못했다. 단지 컴퓨터가 좋아서 프로그래밍을 배웠고, 또 프로그래밍이 좋아서 전산학을 공부했다.

또 좀더 모험을 하고 싶어 유학을 갔으며, 데이터베이스 한 분야에 머물러 있기 보다는 새로운 분야를 개척해보고 싶어서 데이터마이닝 분야에 프론티어로 달려들었다. 중요한 것은 내가 좋아서 한 것이기 때문에 좋은 연구 결과도 낼 수 있었고 또 그렇기 때문에 미국 대학에서 사용되는 데이터베이스나 데이터마이닝 교재에 내가 한 연구나 논문이 많이 인용될 수 있었던 것 같다.

새로운 분야가 끝없이 펼쳐진 길 위에 서서
가만히 생각해보면 나 자신이 축복을 참 많이 받았다고 생각한다. 내가 좋아하는 것을 그래도 평생 할 수 있으니까. 그게 가능했던 건 현재에 머무르지 않고 내가 좋아하는 것을 찾아 항상 도전하는 자세를 갖고 있었기 때문이라 생각한다. 그렇기 때문에 훌륭한 프로그래머가 되기 위해 준비하는 이들에게 이 말을 해주고 싶은 것이다. "도전하는 자세로 삶을 살아가라".

다시 말해 어려운 프로젝트를 해야 할 기회가 생겼을 때 겁먹고 주저하지 말고 달려들어 경험해 보라고. 훌륭한 프로그래머가 되려면 많은 훈련을 통해 담금질 돼야하기 때문이다. 그렇게 하지 않고는 될 수 없다. 또 그렇게 인생을 살지 않으면 아주 먼 옛 날에 이미 당신을 계획한 조물주가 당신을 위해 준비하고 감추어 놓은 소중하고 값진 것들을 경험할 수 없으니까….

돌이켜 보면 지나온 내 인생의 나날들 하나하나가 모두 나에겐 소중한 추억이고 어느 것 하나 버릴 것이 없다. 물론 힘든 일도 참 많았지만, 그 모든 일이 지금처럼 성숙하고 원숙한 30대의 나를 만든 게 아닌가 생각한다. 난 지금도 앞으로 나에게 다가올 것들에 대한 기대로 가슴이 너무 설레고 벅차다. 앞으로 10년 후에는 과연 어떤 모습의 나로 변해 있을까. 또 나에게는 어떤 새로운 만남이나 경험이 준비돼 있는 걸까. '캐스트 어웨이'라는 영화의 마지막 장면에서 끝이 보이지는 않는 여러 갈래의 길을 바라보았던 Chuck Noland의 맘이 이랬을까. @

출처 http://blog.naver.com/kdw1109mania/110013547809

Posted by SB패밀리

[강좌] #6 실행시에 Database Alias생성

이번 강좌는 델파이 어플리케이션에서 ALIAS하고
생성하고 사용하는 것에 대해 많은 도움이 될 것이라고
생각합니다.
일반적으로 alias는 BDE Configuration 유틸리티인
BDECFG.EXE를 이용해서 별도로 지정하죠....

그러나, 더욱 좋은 방법이 있죠....
흐흐....

TDatabase 컴포넌트를 이용해서 어플리케이션 실행하는
도중에 Alias를 생성하여 사용할 수 있죠....

Alias는 데이타베이스 테이블의 경로와 데이타베이스
서버에 대한 연결 파라메터를 지정하게 됩니다.
( Alias가 어떤 기능을 하는지는 다 아시죠... )

Alias를 실행 중에 진행하게 되면 어떤 좋은 점이 있을까요..
그것은 어플리케이션이 실행중에 IDAPI.CFG에 환경설정에
관한 걱정이 필요없어집니다....
미리 데이타베이스에 정보가 있어도 없어도 되니깐...

아래에 예제가 주어져 있습니다...
간단한 예제를 통해서 Run-Time Alias생성에 관해 알아보자구요...

다음은 STANDARD (.DB, .DBF) databases의 생성을 하고
Alias는 TTable Component에 의해서 사용되는 예제입니다...


1 단계
------------
새 프로젝트를 생성한다.

2 단계
------------
Form상에 다음의 컴포넌트를 위치시킨다.

- TDatabase, TTable, TDataSource, TDBGrid, and TButton

3 단계
------------
TDatabase 컴포넌트를 더블클릭하여 TTable, TQuery, 그리고
TTable에 사용될 DatabaseName 프로퍼티에 Alias명을 입력한다.
(예:MyNewAlias)

4 단계
------------
Driver명으로 STANDARD를 선택한다.

5 단계
------------
'PATH='를 지정하기 위하여 TDatabase의 프로퍼티 Params에

PATH= to C:\DELPHI\DEMOS\DATA

를 추가한다.

6 단계
------------
TTable 컴포넌트의 DatabaseName에 TDatabase의
DatabaseName를 할당한다.

7 단계
------------
TTable의 TableName프로퍼티에 테이블 'Customer'를 할당하고
Active를 True로 한다.

8 단계
------------
TDataSource의 DataSet에 TTable.Name을 넣어준다.

9 단계
------------
TDBGrid의 Datasource에 TDataSource.Name을 넣어준다.

10단계
------------
TButton의 OnClick 이벤트에 코드를 추가한다.

11단계
------------
어플리케이션을 실행하고 버튼을 클릭한다.

------------
procedure TForm1.Button1Click(Sender: TObject);
begin
Database1.DatabaseName:= 'MyNewAlias';
Database1.DriverName:= 'STANDARD';

Database1.Params.Clear;
Database1.Params.Add('PATH=C:\DELPHI\DEMOS\DATA');
Table1.DatabaseName:= 'MyNewAlias';
Table1.TableName:= 'CUSTOMER';
Table1.Active:= True;
DataSource1.DataSet:= Table1;

DBGrid1.DataSource:= DataSource1;
End;


소백촌닭
Posted by SB패밀리

-- inserted by bae 07.09.05
 -- PM_users.alluserproj = true 인 레코드를 UserAccess에 IsWritable=read 로 설정하여 추가한다

-- 한번에 여러개의 레코드를 추가하는 방법
 INSERT INTO UserAccess
 (pm_userid, projid, writable)
 SELECT id, @tProjID, 1 FROM pm_users WHERE allprojuser = 1
 
 -- inserted by bae
 -- wbstree 추가 이건 그냥 주석처리
 --INSERT INTO WbsTree
 --(projid, parentid, Name, nodeindex)
 --SELECT (@tProjID, 0, "새 프로젝트", 0)

Posted by SB패밀리

CAST 및 CONVERT

식을 다른 데이터 형식으로 명시적으로 변환합니다. CAST 및 CONVERT는 비슷한 기능을 제공합니다.

구문

CAST 사용

CAST ( expression AS data_type )

CONVERT 사용

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

인수

expression

유효한 Microsoft® SQL Server™ 식입니다. 자세한 내용은 을 참조하십시오.

data_type

bigint, sql_variant 등 대상 시스템 제공 데이터 형식입니다. 사용자 정의 데이터 형식은 사용할 수 없습니다. 자세한 내용은 데이터 형식을 참조하십시오.

length

nchar, nvarchar, char, varchar, binary, varbinary 데이터 형식의 선택적 매개 변수입니다.

style

datetime, smalldatetime 데이터를 문자 데이터(nchar, nvarchar, char, varchar, nchar, nvarchar 데이터 형식)로 변환할 때 사용되는 날짜 형식이나 float, real, money, smallmoney 데이터를 문자 데이터(nchar, nvarchar, char, varchar, nchar, nvarchar 데이터 형식)로 변환할 때 사용되는 문자열 형식의 스타일입니다.

SQL Server는 쿠웨이트 알고리즘을 사용하여 아랍어 날짜 형식을 지원합니다.

다음 표에서 왼쪽 두 열은 datetime 또는 smalldatetime을 문자 데이터로 변환하기 위한 style 값을 나타냅니다. 세기가 포함된 네 자리 연도(yyyy)를 구하려면 style 값에 100을 더합니다.

세기 포함 안함
(yy)
세기 포함
(yyyy)

표준

입력/출력**
- 0 또는 100 (*) 기본값 mon dd yyyy hh:miAM(또는 PM)
1 101 USA mm/dd/yy
2 102 ANSI yy.mm.dd
3 103 영국/프랑스 dd/mm/yy
4 104 독일 dd.mm.yy
5 105 이탈리아 dd-mm-yy
6 106 - dd mon yy
7 107 - Mon dd, yy
8 108 - hh:mm:ss
- 9 또는 109 (*) 기본값 + 밀리초 mon dd yyyy hh:mi:ss:mmmAM(또는 PM)
10 110 USA mm-dd-yy
11 111 일본 yy/mm/dd
12 112 ISO yymmdd
- 13 또는 113 (*) 유럽 기본값 + 밀리초 dd mon yyyy hh:mm:ss:mmm(24h)
14 114 - hh:mi:ss:mmm(24h)
- 20 또는 120 (*) ODBC 표준 yyyy-mm-dd hh:mi:ss(24h)
- 21 또는 121 (*) ODBC 표준(밀리초) yyyy-mm-dd hh:mi:ss.mmm(24h)
- 126(***) ISO8601 yyyy-mm-dd Thh:mm:ss:mmm(공간 없음)
- 130* 쿠웨이트 dd mon yyyy hh:mi:ss:mmmAM
- 131* 쿠웨이트 dd/mm/yy hh:mi:ss:mmmAM

*     기본값(style 0 또는 100, 9 또는 109, 13 또는 113, 20 또는 120, 21 또는 121)은 항상 세기(yyyy)를 반환합니다.

밑에 예제는 Convert함수와 날짜함수를 사용하여서 뽑아온것입니다.

 

1) 오늘 작성된 글중 Top 10개

SELECT TOP 10 m_no, m_table, a.cat_num, m_subject, m_insertdate, m_read, b.binfo_type
from m_board a inner join m_binfo b on a.m_table = b.binfo_table
where convert(varchar(40), m_insertdate, 110) = convert(varchar(40),getdate(), 110) and  m_listnum <> 0 and binfo_type <> 'Fbd' 
order by m_read desc

 

2) 오늘부터 일주일전까지 작성된 글중 Top 10개
SELECT TOP 10 m_no, m_table, a.cat_num, m_subject, m_insertdate, m_read, b.binfo_type
from m_board a inner join m_binfo b on a.m_table = b.binfo_table
where  convert(varchar(40),  m_insertdate, 110) >= convert(varchar(40), Dateadd(day,-7, getdate()), 110) and  m_listnum <> 0 and binfo_type <> 'Fbd' 
order by m_read desc

 

3) 오늘부터 한달전까지 작성된글중 랜덤하게 10개

SELECT TOP 10 m_no, m_table, a.cat_num, m_subject, m_insertdate, m_read, b.binfo_type
from m_board a inner join m_binfo b on a.m_table = b.binfo_table
where  convert(varchar(40),  m_insertdate, 110) >= convert(varchar(40), Dateadd(month,-1, getdate()), 110) and  m_listnum <> 0 and binfo_type <> 'Fbd' 
order by newid()

Posted by SB패밀리

이 대화 상자를 사용하면 데이터베이스의 테이블 사이에 관계를 만들거나 수정할 수 있습니다. 외래 키 관계에서 외래 키 제약 조건은 기본 키나 UNIQUE 제약 조건과 함께 사용되며 지정된 테이블 사이에 참조 무결성을 적용합니다. 예를 들어, Order_Details 테이블에서 ProductID 열에 외래 키 제약 조건을 두어 이 열에 입력한 값이 Products 테이블의 ProductID 열의 기존 값과 일치하도록 할 수 있습니다.

 

 

옵션

선택한 관계

기존 관계를 나열합니다. 관계를 선택하면 오른쪽 표에 해당 속성이 표시됩니다. 목록이 비어 있는 경우 테이블에 정의된 관계가 없음을 의미합니다.

추가

새 관계를 만듭니다. 관계를 유효하게 만들려면 테이블 및 열 사양을 먼저 설정해야 합니다.

삭제

선택한 관계 목록에서 선택한 관계를 삭제합니다. 관계 추가를 취소하려면 이 단추를 사용하여 관계를 제거합니다.

일반 범주

확장하여 만들거나 다시 활성화할 때 기존 데이터 검사테이블 및 열 사양을 표시합니다.

만들거나 다시 활성화할 때 기존 데이터 검사

제약 조건을 만들거나 다시 활성화하기 전부터 테이블에 있던 모든 데이터를 제약 조건에 대해 검사합니다.

테이블 및 열 사양 범주

확장하여 어떠한 테이블의 어떠한 열이 관계에서 외래 키와 기본 키(또는 고유 키)로 사용되는지에 대한 정보를 표시합니다. 이러한 값을 편집하거나 정의하려면 속성 필드의 오른쪽에 있는 줄임표(...)를 클릭합니다.

외래 키 기본 테이블

선택한 관계에서 외래 키로 사용되는 열이 포함된 테이블을 표시합니다.

외래 키 열

선택한 관계에서 외래 키로 사용되는 열을 표시합니다.

Primary/Unique 키 기본 테이블

선택한 관계에서 기본 키(또는 고유 키)로 사용되는 열이 포함된 테이블을 표시합니다.

Primary/Unique 키 열

선택한 관계에서 기본 키(또는 고유 키)로 사용되는 열을 표시합니다.

ID 범주

확장하여 이름설명에 대한 속성 필드를 표시합니다.

이름

관계의 이름을 표시합니다. 새 관계를 만들면 테이블 디자이너의 활성 창에 있는 테이블을 기반으로 한 기본 이름이 새 관계에 지정됩니다. 언제든지 이름을 변경할 수 있습니다.

설명

관계에 대해 설명합니다. 더 자세한 설명을 기록하려면 설명을 클릭한 다음 속성 필드의 오른쪽에 있는 줄임표(...)를 클릭합니다. 이렇게 하면 텍스트를 쓸 수 있는 더 큰 영역이 제공됩니다.

테이블 디자이너 범주

확장하여 만들거나 다시 활성화할 때 기존 데이터 검사복제에 적용에 대한 정보를 표시합니다.

복제에 적용

복제 에이전트가 이 테이블에서 삽입, 업데이트 또는 삭제를 수행할 때 제약 조건을 적용할지 여부를 나타냅니다. 자세한 내용은 NOT FOR REPLICATION으로 제약 조건, ID, 및 트리거 제어를 참조하십시오.

외래 키 제약 조건 적용

관계를 맺고 있는 열의 데이터를 변경할 때 외래 키 관계의 무결성 제약 조건을 위반하게 되는 경우 이러한 데이터를 변경할 수 있는지 여부를 지정합니다. 이러한 변경을 허용하지 않으려면 를 선택하고, 이를 허용하려면 아니요를 선택합니다.

INSERT 및 UPDATE 사양 범주

확장하여 관계의 삭제 규칙업데이트 규칙에 대한 정보를 표시합니다.

삭제 규칙

외래 키 관계를 맺고 있는 데이터가 포함된 행을 사용자가 삭제하려 할 때 적용할 결과를 지정합니다.

  • 작업 안 함 삭제가 허용되지 않고 DELETE가 롤백된다는 오류 메시지가 나타납니다.

  • 계단식 배열 외래 키 관계에 관련된 데이터가 포함된 모든 행을 삭제합니다.

  • Null 설정 테이블의 모든 외래 키 열에 null 값을 사용할 수 있으면 값을 null로 설정합니다. SQL Server 2005 에만 적용됩니다.

  • 기본값 설정 테이블의 모든 외래 키 열에 기본값이 정의되어 있으면 열에 정의된 기본값으로 값을 설정합니다. SQL Server 2005 에만 적용됩니다.

업데이트 규칙

외래 키 관계를 맺고 있는 데이터가 포함된 행을 사용자가 업데이트하려 할 때 적용할 결과를 지정합니다.

  • 작업 안 함 삭제가 허용되지 않고 DELETE가 롤백된다는 오류 메시지가 나타납니다.

  • 계단식 배열 외래 키 관계에 관련된 데이터가 포함된 모든 행을 삭제합니다.

  • Null 설정 테이블의 모든 외래 키 열에 null 값을 사용할 수 있으면 값을 null로 설정합니다. SQL Server 2005 에만 적용됩니다.

  • 기본값 설정 테이블의 모든 외래 키 열에 기본값이 정의되어 있으면 열에 정의된 기본값으로 값을 설정합니다. SQL Server 2005 에만 적용됩니다.


출처 :MSDN

Posted by SB패밀리

sql server 2000에서 sp_executesql 을 사용할 때 제약조건이 있었는데,

sql 문을 4000자 이상 처리할 수 없다는 것입니다.

sql 문은 유니코드 문자열(nvarchar 나 nchar)이어야 하기 때문에 최대 4000자까지 쓸 수 있습니다.
참고로 ntext 형은 변수 선언을 할 수 없습니다.

 

예를 들어 다음과 같은 쿼리가 있다고 해보죠.

declare @sql nvarchar(4000)
set @sql = 'select * from tableA .....' 
exec dbo.sp_executesql @sql

 

만약 @sql에 4000자가 넘어가는 문장을 넣게되면 @sql은 4000자에서 문장을 자를것이고, 따라서 sp_executesql은 실패하게 될 것입니다.

 

하지만 sql server 2005에서는 nvarchar(max)라를 데이터 타입이 추가되었고,

변수 선언이 가능해 졌습니다.

다음과 같이 위 쿼리를 수정하면 sql server 2005에서는 4000자 이상되는

동적 쿼리도 처리가 가능해 집니다.

declare @sql nvarchar(max)
set @sql = 'select * from tableA .....' 
exec dbo.sp_executesql @sql 

Posted by SB패밀리

<파워빌더 ODBC 인터페이스> 

  
 다음은 파워빌더7.0과 인포메이커 애플리케이션이, ODBC를 사용하여 데이터베이스에 
 접속하고자 할 때 필요한 파일 목록입니다. 

  
 파일명 설명

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

 PBODB80.DLL PowerBuilder ODBC interface

 PBODB80.INI PowerBuilder ODBC initialization file

 

 설치된 경로 > C:Program FilesSybaseSharedPowerBuilder

 설치될 경로 > 설치할 프로그램 폴더, System Path 또는 Path가 지정된 특정 폴더

  INI파일과 DLL파일은 반드시 같은 디렉토리에 위치해야 합니다. 

  
  

 <마이크로소프트 ODBC 파일> 

  
 개발된 애플리케이션이 ODBC를 이용하여, 데이터베이스에 접속할 경우,

 다음의 마이크로소프트 ODBC 3.5파일들이 필요합니다.

 보통 윈도우 설치시 함께 설치되어 있습니다.

 다시 설치할 필요가 있으면 설치 CD 안에 Support 폴더에 있는 MDAC_TYP.EXE을

 실행하여 업데이트할 수 있습니다. 

  
 파일명 설명

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

 DS16GT.DLL Microsoft ODBC driver manager, DLLs, and Help files

 DS32GT.DLL

 ODBC32.DLL

 ODBC32GT.DLL

 ODBCAD32.EXE

 ODBCCP32.CPL

 ODBCCP32.DLL

 ODBCCR32.DLL

 ODBCINST.CNT

 ODBCINST.HLP

 ODBCINT.DLL

 ODBCTRAC.DLL

 

 설치된 경로 > Windows system directory

 설치될 경로 > Windows system directory 

    

 <어댑티브 서버 애니웨어 파일> 

  
 개발한 PowerBuilder 애플리케이션이 어댑티브 서버 에니웨어(ASA)데이터베이스를 사용한다면,

 배포시 ASA의 ODBC 데이터베이스 드라이버와 ASA DBMS를 함께 배포하셔야 합니다.

 개발된 애플리케이션이 독립형(stand-alone) 데이터베이스를 사용할 경우에는

 ASA의 데스크탑 런타임 모듈을 최종 사용자의 PC에 무상으로 배포하실 수 있습니다.

 이 런타임 모듈은 사용자가 데이터베이스내에 있는 데이터를 조회하거나 변경하는 것은 허용하나,

 데이터베이스의 스키마(schema)를 변경하는 것은 허용되지 않습니다.

 또한 트랜젝션 로그(Transaction logs)나 저장 프로시져(Stored procedures),

 트리거(Trigger)를 지원하지 않습니다.

 ASA(Adaptive Server Anywhere)드라이버와 런타임 엔진 그리고 기타 지원 파일들을 모두 인스톨

 하실 때는 파워빌더 인스톨 CD에 있는 "Support" 디렉토리에 있는 파일들을 설치 하십시오.

 

 파일명 설명

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

 DBODBC7.DLL ASA ODBC driver

 DBBACKUP.EXE ASA backup utility

 DBCON7.DLL Connection dialog box, required if you do not provide your own dialog box and

  your end users are to create their own data sources, if they need to enter

  user IDs and passwords when connecting to the database, or if they need to

  display the Connection dialog box for any other purpose

 DBISQLC.EXE Interactive SQL utility

 DBLGEN7.DLL Language-specific string library (EN indicates the English version)

 DBLIB7.DLL Interface library

 DBODTR7.DLL ODBC translator, required if your application relies on OEM to ANSI character set
 conversion

 DBTOOL7.DLL ASA database tools

 DBUNLOAD.EXE ASA unload utility

 DBVALID.EXE ASA validation utility

 RTENG7.EXE 제한적 용도의 런타임 엔진

 DBCTRS7.DLL Performance utility

 DBSERV7.DLL Server utility

 DBWTSP7.DLL Tools support

 

 설치된 경로 > C:Program FilesSybaseSQL Anywhere 7win32

 설치될 경로 > 설치할 프로그램 폴더, System Path 또는 Path가 지정된 특정 폴더

  기타지원 파일들은 반드시 DBODBC7.DLL이 있는 디렉토리에 설치되어야 합니다.

 ODBC 정보설정> ODBC에 대한 정보를 레지스트리에 등록해야 합니다.

 

 - ODBC.INI

 프로그램을 특정 데이터소스에 ODBC를 통해 연결하려면 레지스트리 정보 중 'ODBC.INI' 항목에

 데이터소스에 대한 정의가 필요합니다.

 'ODBC.INI'항목은 'HKEY_CURRENT_USER' 또는 'HKEY_LOCAL_MACHINE'에 있는데 앞에 것은

 사용자 DSN에 등록되는 내용이며 뒤에 것은 시스템 DSN에 등록되는 것입니다.

 DSN에 대한 설정내용은 제어판의 'ODBC 데이터 원본 관리자'에서 확인할 수 있습니다.

 이 내용은 프로그램이 데이베이스를 구동할 때 제공할 정보들입니다.

 

 [HKEY_CURRENT_USERSOFTWAREODBCODBC.INIMyApp DB]

 "Driver"="C:Program FilesSybaseSQL Anywhere 7win32dbodbc7.dll"

 "Start"="c:program filessybaseSQL Anywhere 7win32rteng7.exe -c8m"

 "UID"="dba"

 "PWD"="sql"

 "Description"="Database for my application"

 "DatabaseFile"="C:Program Filesmyappsmyapp.db"

 "AutoStop"="Yes"

 

 [HKEY_CURRENT_USERSOFTWAREODBCODBC.INIODBC Data Sources]

 "MyApp DB"="Adaptive Server Anywhere 7.0"

 

 - ODBCINST.INI

 프로그램이 실행될 PC에 설치된 ODBC 드라이버에 대한 정보입니다.

 드라이버 설치정보는 제어판의 'ODBC 데이터 원본 관리자'에서 확인할 수 있습니다.

 

 [HKEY_LOCAL_MACHINESOFTWAREODBCODBCINST.INIODBC Drivers]

 "Adaptive Server Anywhere 7.0"="Installed"

 "PB Merant OEM 3.60 32-BIT Sybase"="Installed"

 

 [HKEY_LOCAL_MACHINESOFTWAREODBCODBCINST.INIAdaptive Server Anywhere 7.0]

 "Driver"="c:program filessybaseSQL Anywhere 7win32dbodbc7.dll"

 "Setup"="c:program filessybaseSQL Anywhere 7win32dbodbc7.dll"
 
 질문)

 "kernel32.dll" 에 포함되어 있는 CreatFile,WriteFile,CloseHandle 함수를 쓸려고 하는데

 파워빌더 Global External Function 에서 어떻게 변수들을 정의하고 값을 정의 하는지 알고 싶어서요.

 MSDN 사이트 들어가봐도 약간 찾기가 힘드네요..그럼 수거하세요.
Posted by SB패밀리

날짜 관련 함수입니다.
          
  2.1.1 GETDATE() 함수

          시스템의 날짜를 리턴합니다.
          
        SELECT GETDATE()
        2002-05-24 오전 10:51:05

        SELECT GETDATE()+100
        2002-09-01 오전 10:51:05



  2.1.2 CONVERT() 함수
  
          결과값의 데이타 타입을 변환시킵니다.
          
        SELECT CONVERT(varchar(30), GETDATE(),100)
        May 24 2002 10:51AM

        SELECT CONVERT(varchar(30), GETDATE(),101)
        05/24/2002

        SELECT CONVERT(varchar(30), GETDATE(),102)
        2002.05.24

        SELECT CONVERT(varchar(30), GETDATE(),103)
        24/05/2002

        SELECT CONVERT(varchar(30), GETDATE(),104)
        24.05.2002

        SELECT CONVERT(varchar(30), GETDATE(),105)
        24-05-2002

        SELECT CONVERT(varchar(30), GETDATE(),106)
        24 May 2002

        SELECT CONVERT(varchar(30), GETDATE(),107)
        May 24, 2002

        SELECT CONVERT(varchar(30), GETDATE(),108)
        10:51:05

        SELECT CONVERT(varchar(30), GETDATE(),109)
        May 24 2002 10:51:05:140AM

        SELECT CONVERT(varchar(30), GETDATE(),110)
        05-24-2002

        SELECT CONVERT(varchar(30), GETDATE(),111)
        2002/05/24

        SELECT CONVERT(varchar(30), GETDATE(),112)
        20020524

        SELECT CONVERT(varchar(30), GETDATE(),113)
        24 May 2002 10:51:05:160

        SELECT CONVERT(varchar(30), GETDATE(),114)
        10:51:05:160



  2.1.3 DATEPART() 함수

        날짜에서 지정한 날자형식부분만 추출해줍니다        
        형식: DATEPART(날짜형식, 날짜)
        
        SELECT DATEPART(yy, GETDATE())
        2002

        SELECT DATEPART(mm, GETDATE())
        5

        SELECT DATEPART(dd, GETDATE())
        24

        SELECT DATEPART(hour, GETDATE())
        10

        SELECT DATEPART(mi, GETDATE())
        51

        SELECT DATEPART(ss, GETDATE())
        5

        SELECT DATEPART(dw, GETDATE())
        6


        년/월/일/시/분/초/요일을 숫자로  보여준 예제입니다.

  2.1.4 YEAR() , MONTH() , DAY() 함수         
          
          해당 년,월,일을 각각 뽑아줍니다.
          형식: YEAR(날짜) , MONTH(날짜) , DAY(날짜)

        SELECT YEAR(GETDATE())
        2002

        SELECT MONTH(GETDATE())
        5

        SELECT DAY(GETDATE())
        24



  2.1.5 DATEADD() 함수         
  
          
          DATEADD함수는 날짜에 지정한 만큼을 더합니다.
        형식: DATEADD(날짜형식, 더할 값, 날짜)


        SELECT DATEADD(mm,20,GETDATE())
        2004-01-24 오전 10:51:05


        현재날짜에 월에 20을 더한 날짜를 출력하라.
        
        SELECT DATEADD(dd,100,GETDATE())
        2002-09-01 오전 10:51:05


        오늘부터 100일 후의 날짜를 출력하라.
        
  2.1.6 DATEDIFF() 함수         
  
        DATEDIFF함수는 두 날짜사이의 날짜형식에 지정된 부분을 돌려줍니다.
        형식: DATEDIFF(날짜형식, 시작 날자, 끝 날짜)


        SELECT DATEDIFF(dd,GETDATE(),'3000.1.1')
        364369


        현재날짜와 3000.1.1일 사이의 일수는 얼마일까.??
        
        SELECT DATEDIFF(MM,GETDATE(),'2003.1.1')
        8


        현재날짜와 2003.1.1일 사이의 월수는 얼마일까.??

  2.1.7 DATENAME() 함수         
  
        DATENAME함수는 지정한 날짜의 날자형식의 이름을 돌려줍니다.
        형식: DATENAME(날짜형식, 날짜)    

        SELECT DATENAME(mm,GETDATE())
        May

        SELECT DATENAME(dd,GETDATE())
        24

        SELECT DATENAME(dw,GETDATE())
        Friday

Posted by SB패밀리

기억이 잘 안되고 아주 가끔 사용되는 팁이라서 기록해 둠


* 방금 INSERT 한 자동증가 값(ID) 가져오기
 SELECT @@IDENTITY (현재 세션에서만 사용가능)

* 현재 테이블의 가장 큰 값 가져오기
 SELECT IDENT_CURRENT('테이블명')

* 수행된 SQL문에 영향을 받은 행의 수
 SELECT @@ROWCOUNT

* 테이블 정보보기
 EXEC SP_HELP 테이블

* 컬럼 정보보기
 EXEC SP_COLUMNS 테이블

* 엘리어스 사용
 SELECT 필드 AS 엘리어스명 FROM 테이블명 (별칭에 특수문자가 있다면 []를 사용

* 일부분만 가져오기
 SELECT TOP N 컬럼 FROM 테이블명  (N 레코드수만큼 가져오기)

* 패턴매칭 (+키워드 예약어)
 SELECT 컬럼 FROM 테이블 WHERE 컬럼 LIKE '%키워드%'
  _ : 어떤 것이든 한 문자
  % : 없거나 아무 글자가 포함되거나
  [ ] : [ ] 안에 있는 글자들 - [B-F]
  [^] : ^다음에 있는 글자를 제외한 다른 것

* 중복제거
 SELECT DISTINCT 컬럼 FROM 테이블

               

Posted by SB패밀리