출처 : http://laigo.kr/723


SQL Server 2012 에서 XML 문서를 테이블에 Bulk Insert 하는 방법과 XQuery 를 사용하여 XML 데이터를 검색하는 몇 가지 예제를 아래와 같이 정리하였습니다.

 

 

1. XML 원본 문서를 테이블에 Bulk Insert 하는 방법

CREATE DATABASE XMLDB
GO

 

USE XMLDB
GO

 

CREATE TABLE TBL_XML (
 ID  INT IDENTITY PRIMARY KEY,
 XMLDATA XML 
)
GO

INSERT INTO TBL_XML(XMLDATA) 
SELECT * FROM OPENROWSET (
     BULK 'D:\SQL\BOOKS.XML', SINGLE_BLOB) AS x;

 

 

 

2. XQuery 를 사용하여 XML 데이터 검색 예제 

CREATE TABLE TBL_XQUERY (
 ID  INT IDENTITY PRIMARY KEY,
 XMLDATA XML 
)
GO

INSERT INTO TBL_XQUERY VALUES ('
 <CATALOG> 
  <book id="bk101">
   <author>Gambardella, Matthew</author>
   <title>XML Developer''s Guide</title>
   <genre>Computer</genre>
   <price>44.95</price>
   <publish_date>2000-10-01</publish_date>
   <description>An in-depth look at creating applications with XML.</description>
  </book> 
 </CATALOG>
')

INSERT INTO TBL_XQUERY VALUES ('
 <CATALOG> 
  <book id="bk102">
    <author>Ralls, Kim</author>
    <title>Midnight Rain</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-12-16</publish_date>
    <description>A former architect battles corporate zombies, n evil sorceress, and her own childhood to become queen of the world.</description>
  </book>
 </CATALOG>
')

INSERT INTO TBL_XQUERY VALUES ('
 <CATALOG> 
    <book id="bk103">
    <author>Corets, Eva</author>
    <title>Maeve Ascendant</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-11-17</publish_date>
    <description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description>
    </book>
 </CATALOG>
')

 

 

SELECT XMLDATA.query('/CATALOG/book')
FROM TBL_XQUERY
WHERE ID = 2
/*
<book id="bk102">
  <author>Ralls, Kim</author>
  <title>Midnight Rain</title>
  <genre>Fantasy</genre>
  <price>5.95</price>
  <publish_date>2000-12-16</publish_date>
  <description>A former architect battles corporate zombies, n evil sorceress, and her own childhood to become queen of the world.</description>
</book>
*/

 


SELECT XMLDATA.value ( '(/CATALOG/book/@id)[1]', 'char(5)' ) AS 'Book id'
FROM TBL_XQUERY
/*
bk101
bk102
bk103
*/

 


SELECT XMLDATA 
FROM TBL_XQUERY
WHERE XMLDATA.exist('/CATALOG/book[@id="bk103"]') = 1
/*
<CATALOG>
  <book id="bk103">
    <author>Corets, Eva</author>
    <title>Maeve Ascendant</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-11-17</publish_date>
    <description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description>
  </book>
</CATALOG>
*/

 


SELECT 
 nCol.value('@id', 'char(5)') AS 'Book id', 
 nCol.value('(author)[1]', 'varchar(10)') AS author,
 nCol.value('(title)[1]', 'varchar(50)') AS title,
 nCol.value('(genre)[1]', 'varchar(10)') AS genre
FROM TBL_XQUERY 
CROSS APPLY XMLDATA.nodes('/CATALOG/book') AS nTbl(nCol)
ORDER BY ID
/*
bk101 Gambardell XML Developer's Guide Computer
bk102 Ralls, Kim Midnight Rain   Fantasy
bk103 Corets, Ev Maeve Ascendant   Fantasy
*/

 

 

 

[참고자료]

Examples of Bulk Import and Export of XML Documents (SQL Server)
http://msdn.microsoft.com/en-us/library/ms191184.aspx

 

XQuery 언어 참조(SQL Server)
http://msdn.microsoft.com/ko-kr/library/ms189075.aspx

 


서버 개발하다 보면 DB에 내장 프로시저가 많아지는데
이것도 나중에 관리하는게 일이 되어 버린다.

하여튼, 특정 단어가 쓰였는지 확인하려면

--내장 프로시저 검색
SELECT * FROM sysobjects WHERE id IN (
 SELECT id FROM syscomments WHERE text LIKE '%검색할 단어%'
)

위 쿼리를 실행시키면 된다.

그대로 복사해서 검색할 단어에 프로시저에서 사용할법한
(SELECT 나 UPDATE 등 테이블 조작하는 필드명을 검색한다거나...)
단어를 넣어서 실행하면
결과 테이블이 뜨는데, 그 내장 프로시저를 찾아가면 된다.

#include <stdio.h>
#include <errno.h>
#include <mysql.h>

MYSQL mysql;

// 쿼리 질의를 한다
void sql_qur(char *sql_query)
{
     printf("input sql query is %s\n", sql_query);
     if( mysql_real_query(&mysql, sql_query, strlen(sql_query)) )
     {
          perror( mysql_error(&mysql) );
          exit( 1 );
     }
}

// 쿼리 질의로 온 결과를 모두 출력한다.
void sql_print_result(char *result)
{
     MYSQL_RES *res;
     MYSQL_ROW row;
     MYSQL_FIELD *fld;
     int fields;

     if( !(res=mysql_store_result(&mysql)) )
     {
          perror( mysql_error(&mysql) );
          exit( 1 );
     }
 
     sprintf(result, "");

     while( (row=mysql_fetch_row(res)) )
     {
          int     i;
     
          for( i=0 ; i<mysql_num_fields(res) ; i++ )
          {
              fld = mysql_fetch_field_direct( res, i );

              if(i == 0)
                  sprintf( result, "%s%20s: %s", result, fld->name, row[i] );
              else
                  sprintf( result, "%s\n%20s: %s", result, fld->name, row[i] );

              if( !strlen(row[i]) )
              {
                  mysql_free_result(res);
                  mysql_close(&mysql);
                  exit(0);
              }
          }
          sprintf( result, "%s\n\n", result );
      }

      mysql_free_result(res);
}

// 쿼리를 받음 단, 한줄에 한개의 쿼리가 찍힌다
void sql_get_result(char *result)
{
        MYSQL_RES *res;
        MYSQL_ROW row;
        int line = 0;
 
        if( !(res=mysql_store_result(&mysql)) )
        {
                perror( mysql_error(&mysql) );
                exit( 1 );
        }
 
        sprintf(result, "");
 
        while( (row=mysql_fetch_row(res)) )
        {
                int     i;
 
                for( i=0 ; i<mysql_num_fields(res) ; i++ )
                {
                        if(i == 0 && line == 0)
                               sprintf( result, "%s", row[i] );
                        else
                               sprintf( result, "%s\n%s", result, row[i] );
 
                        if( !strlen(row[i]))
                        {
                                mysql_free_result(res);
                                mysql_close(&mysql);
                                exit(0);
                         }
                 }
                ++line;
        }
        result[strlen(result)] = '\0';
        mysql_free_result(res);
}

void main(void)
{
        char input_query[100];
        mysql_init( &mysql );

        if( !mysql_real_connect(&mysql,
           "localhost",            // host
           "user",          // user
           "pw",       // passwd
           "db_name",          // db
           3306,                   // port
           NULL,
           0) )
        {
         perror( mysql_error(&mysql) );
         exit( 1 );
        }

        // user 테이블을 출력한다.
        sql_qur("select * from user;");
        sql_print_result(&input_query);
        printf("sql result %s\n", input_query);
 
        // test01 ID에 대한 password 값을 구한다.
        sql_qur("select password from user where ID='test01';");
        sql_get_result(&input_query);
        printf("sql result %s\n", input_query);
 
        // 질의를 입력 받아서 그 결과를 계속 출력
        while(1)
        {
                printf("input sql query! : ");
                sql_qur(gets(input_query));

                sql_get_result(&input_query);
                printf("\nsql result %s\n", input_query);
        }

        mysql_close(&mysql);
}


 출처 카페 > 세은파파의 프로그래밍 하자 .. | 세은파파
원문 http://cafe.naver.com/cyberzone/172
MySQL C API

 1) my_ulonglong mysql_affected_rows(MYSQL* mysql)
        INSERT, UPDATE, DELETE 등의 query로 영향을 받은 ROW의 수를 리턴한다.

2) void mysql_close(MYSQL* mysql) 서버와의 연결을 종료한다.

3) void mysql_data_seek(MYSQL_RES* result, unsigned int offset)
        result에서 임의의 ROW에 접근을 하도록 하는 함수이다. offset이 row의 번호를
        나타낸다. 0이면 처음 ROW, mysql_num_rows( result ) - 1 은 마지막 row를 나타낸다.

4) unsigned int mysql_errno(MYSQL* mysql) 
    가장 최근에 mysql에 일어난 에러의 번호를 리턴한다.

5) char* mysql_error(MYSQL* mysql) 가장 최근에 일어난 에러 메시지를 리턴한다.

6) MYSQL_FIELD* mysql_fetch_field(MYSQL_RES* result)
        한번 호출할 때마다 한 나의 필드에 대한 정보를 리턴한다.

7) MYSQL_FIELDS* mysql_fetch_fields(MYSQL_RES* result)
        배열 형대로 result의 필드에 대한 정보를 한꺼번에 리턴한다.

8) MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL* mysql, MYSQL_FIELD_OFFSET offset)
        임의의 필드에 접근을 하도록 한다.

9) MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES* result)
        현재 필드의 offset을 리턴한다.

10) void mysql_free_result(MYSQL_RES* result)
        result에 할당된 메모리를 해제한다.

11) MYSQL* mysql_init(MYSQL* mysql)
        mysql 객체를 초기화 한다. 인자가 NULL이면 새로운 MYSQL 객체를 생성하고, 초기화 하여 리턴한다.

12) MYSQL_RES* mysql_list_dbs(MYSQL* mysql, const char* wild)
        현재 서버에 있는 데이타베이스의 목록을 리턴한다. wild는 MySQL에서
        사용할 수 있는 정규식을 나타낸다.    
        result = mysql_list_dbs( &mysql,"%" )
        는 모든 데이타베이스를 리턴하는 예이다.(%는 '모든'을 나타낸다)

13) MYSQL_RES* mysql_list_tables(MYSQL* mysql, const char* wild)
        현재 데이타베이스에 있는 테이블들의 목록을 리턴한다.

14) unsigned int mysql_num_fields(MYSQL_RES*result) 혹은
    unsigned int mysql_num_fields(MYSQL* mysql)
 
    필드의 수를 리턴한다.

15) my_ulonglong mysql_num_rows(MYSQL_RES* result)
        result에 총 몇 개의 ROW가 있는지 리턴한다. query 수행 후
        mysql_store_result()를 호출하였을 경우에만 사용할 수 있고,  
        mysql_use_result()는 사용할 수 없다.

16) int mysql_ping(MYSQL* mysql) 
        서버에 연결 중인지를 리턴한다. 연결이 끊어 졌을 경우, 다시
        연결을 시도한다. 서버와 연결을 한 후 오랫동안 가만히 있으면
        서버가 연결을 끊어버리는데, 이런 경우에 사용한다.

17) int mysql_query(MYSQL* mysql, const char* query)
        query가 포인트 하는 쿼리를 수행한다. query의 끝은 NULL 문자이다.
        성공적으로 query를 수행하였으면 0을 리턴한다.

18) MYSQL* mysql_real_connect(MYSQL* mysql, const char* host, const char* user,
const char* passwd, const char* db, uint port, const char* unix_socket,
unit client_flag )
 
         host와의 연결을 시도한다.

19) int mysql_real_query(MYSQL* mysql, const char* query, unsigned int length)
         mysql_query()처럼 query를 수행하나, query의 끝이 legnth인 것이 다르다.

20) MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES* result) 
        현재 ROW의 offset을 리턴한다.

21) int mysql_select_db(MYSQL* mysql, const char* db)
        사용하고자 하는 database를 변경한다. mysql_query()를 이용하여 "use db이름"
        의 query를 수행해도 같은 결과를 얻는다.

22) int mysql_shutdown(MYSQL* mysql)
        서버를 종료시킨다. 현재 사용자에게 shutdown 권한이 있어야 한다.

23) MYSQL_RES* mysql_store_result(MYSQL* mysql)
        query의 수행 결과를 서버로부터 한 번에 모두 받아 온다.

24) MYSQL_RES* mysql_use_result(MYSQL* mysql)
        query의 수행 결과를 서버로부터 한 개의 ROW 씩 받아 온다.
   


간단한 예   
   
***********************************************************
1: #include <stdio.h>
2: #include <mysql.h>
3: #include <errno.h>
4:
5: void main(void)
6: {
7: MYSQL mysql ;
8: MYSQL_RES* res ;
9: MYSQL_ROW row ;
10: int fields ;
11:
12: mysql_init(&mysql) ;
13:
14: if(!mysql_real_connect(&mysql, NULL, "사용자","암호", "test" ,3306, (char *)NULL, 0))
15: {
16:     printf("%s\n",mysql_error(&mysql));
17:     exit(1) ;
18: }
19:
20: if(mysql_query(&mysql, "USE super") )
     // mysql_query()는 query 수행시에 에러가 나게 되면
     // 0이 아닌 값을 리턴한다.
     {
          printf("%s\n", mysql_error(&mysql) ;
          exit(1) ;
     }
21: if(mysql_query(&mysql, "SELECT * FROM dome") )
     {
          printf("%s\n", mysql_error(&mysql) ;
          exit(1) ;
     }
22:
23: res = mysql_store_result( &mysql ) ;
24: fields = mysql_num_fields(res) ;
25:
26: while( ( row = mysql_fetch_row( res ) ))
27: {
28:      for( cnt = 0 ; cnt < fields ; ++cnt)
29:      printf("%12s ", row[cnt]) ;
30:
31:      printf("\n") ;
32: }
33:
34: mysql_free_result( res ) ;
35: mysql_close(&mysql) ;
36: }

*****************************************************

+ Recent posts