https://github.com/erikh/ruby-dbi |
설치를 시작하기 전에 루트 액세스 권한이 있는지 확인하세요. 이제 아래 단계에 따라 설치하세요.
1단계
git clone https://github.com/erikh/ruby-dbi.git
또는 zip 패키지를 직접 다운로드하여 압축을 풉니다.
2단계
ruby-dbi-master 디렉토리에 들어가서 구성할 디렉토리의 setup.rb 스크립트를 사용하세요. 가장 일반적으로 사용되는 구성 명령은 config 매개변수 뒤에 매개변수가 없는 것입니다. 이 명령은 기본적으로 모든 드라이버를 설치하도록 구성됩니다.
$ ruby setup.rb config
더 구체적으로 --with 옵션을 사용하여 사용하려는 특정 부분을 나열할 수 있습니다. 예를 들어 기본 DBI 모듈과 MySQL DBD 레이어 드라이버만 구성하려면 다음 명령을 입력합니다.
$ ruby setup.rb config --with=dbi,dbd_mysql
3단계
마지막 단계는 드라이버를 생성하는 것이며, 다음 명령을 사용하여 설치합니다.
$ ruby setup.rb setup
$ ruby setup.rb install
MySQL 데이터베이스를 사용한다고 가정합니다. 데이터베이스에 연결하기 전에 다음을 확인하세요.
데이터베이스 TESTDB를 생성했습니다.
TESTDB에 EMPLOYEE 테이블을 생성했습니다.
이 테이블에는 FIRST_NAME, LAST_NAME, AGE, SEX 및 INCOME 필드가 있습니다.
TESTDB에 액세스하려면 사용자 ID "testuser"와 비밀번호 "test123"을 설정하세요.
Ruby 모듈 DBI가 컴퓨터에 올바르게 설치되었습니다.
당신은 MySQL 튜토리얼을 시청하고 MySQL의 기본 작동을 이해했습니다.
다음은 MySQL 데이터베이스 "TESTDB"에 연결하는 예입니다.
#!/usr/bin/ruby -w
require "dbi"
begin
# 连接到 MySQL 服务器
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
# 获取服务器版本字符串,并显示
row = dbh.select_one("SELECT VERSION()")
puts "Server version: " + row[0]
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
# 断开与服务器的连接
dbh.disconnect if dbh
end
이 스크립트를 실행하면 Linux 시스템에서 다음과 같은 결과가 생성됩니다.
Server version: 5.0.45
데이터 소스와 연결이 설정되면 데이터베이스 핸들(Database Handle)이 반환되어 이후 사용을 위해 dbh에 저장됩니다. 그렇지 않으면 dbh가 nil 값인 e.err 및 로 설정됩니다. e::errstr는 각각 오류 코드와 오류 문자열을 반환합니다.
마지막으로, 이 프로그램을 종료하기 전에 반드시 데이터베이스 연결을 종료하고 리소스를 해제하시기 바랍니다.
데이터베이스 테이블에 레코드를 생성하려면 INSERT 연산을 사용해야 합니다.
데이터베이스 연결이 설정되면 do 메서드나 prepare 및 execute 메서드를 사용하여 테이블을 생성하거나 데이터 테이블에 삽입된 레코드를 생성할 수 있습니다.
do 문 사용
행을 반환하지 않는 문은 do 데이터베이스 처리 방법을 호출하여 수행할 수 있습니다. 이 메서드는 명령문 문자열 매개변수를 사용하고 명령문의 영향을 받은 행 수를 반환합니다.
dbh.do("DROP TABLE IF EXISTS EMPLOYEE")
dbh.do("CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )" );
마찬가지로 SQL INSERT 문을 실행하여 EMPLOYEE 테이블에 삽입할 레코드를 생성할 수 있습니다.
#!/usr/bin/ruby -w
require "dbi"
begin
# 连接到 MySQL 服务器
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
dbh.do( "INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME,
AGE,
SEX,
INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)" )
puts "Record has been created"
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# 断开与服务器的连接
dbh.disconnect if dbh
end
prepare 및 execute
사용 DBI의 prepare 및 execute 메소드를 사용하여 Ruby 코드에서 SQL 문을 실행할 수 있습니다.
레코드를 생성하는 단계는 다음과 같습니다.
INSERT 문이 포함된 SQL 문을 준비합니다. 이 작업은 prepare 방법을 사용하여 수행됩니다.
SQL 쿼리를 실행하고 데이터베이스의 모든 결과를 선택하세요. 이 작업은 execute 메서드를 사용하여 수행됩니다.
출시문 핸들. 이 작업은 finish API를 사용하여 수행됩니다.
모든 것이 순조롭게 진행되면 해당 작업을 커밋하고, 그렇지 않으면 롤백하여 거래를 완료할 수 있습니다.
다음은 이 두 가지 방법을 사용하는 구문입니다.
sth = dbh.prepare(statement)
sth.execute
... zero or more SQL operations ...
sth.finish
이 두 가지 방법은 bind 값을 SQL 문에 전달하는 데 사용할 수 있습니다. 때로는 입력되는 값이 미리 제공되지 않을 수 있으며, 이 경우 경계 값이 사용됩니다. 실행() API를 통해 전달되는 실제 값 대신 물음표(?)를 사용합니다.
다음 예에서는 EMPLOYEE 테이블에 두 개의 레코드를 생성합니다.
#!/usr/bin/ruby -w
require "dbi"
begin
# 连接到 MySQL 服务器
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare( "INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME,
AGE,
SEX,
INCOME)
VALUES (?, ?, ?, ?, ?)" )
sth.execute('John', 'Poul', 25, 'M', 2300)
sth.execute('Zara', 'Ali', 17, 'F', 1000)
sth.finish
dbh.commit
puts "Record has been created"
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# 断开与服务器的连接
dbh.disconnect if dbh
end
여러 INSERT가 동시에 사용되는 경우 매번 do를 호출하는 것보다 먼저 문을 준비한 다음 루프에서 여러 번 실행하는 것이 더 효율적입니다. 루프를 통해 훨씬 더.
모든 데이터베이스에 대한 READ 작업은 데이터베이스에서 유용한 정보를 얻는 것을 의미합니다.
데이터베이스 연결이 설정되면 데이터베이스에 쿼리할 준비가 된 것입니다. do 메서드나 prepare 및 execute 메서드를 사용하여 데이터베이스 테이블에서 값을 가져올 수 있습니다.
기록을 가져오는 단계는 다음과 같습니다.
필요한 조건에 따라 SQL 쿼리를 준비합니다. 이 작업은 prepare 방법을 사용하여 수행됩니다.
SQL 쿼리를 실행하고 데이터베이스의 모든 결과를 선택하세요. 이 작업은 execute 메서드를 사용하여 수행됩니다.
결과를 하나씩 가져와서 출력해 보세요. 이 작업은 fetch 메서드를 사용하여 수행됩니다.
출시문 핸들. 이 작업은 finish 메서드를 사용하여 수행됩니다.
다음 예에서는 EMPLOYEE 테이블에서 급여(salary)가 1000을 초과하는 모든 레코드를 쿼리합니다.
#!/usr/bin/ruby -w
require "dbi"
begin
# 连接到 MySQL 服务器
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare("SELECT * FROM EMPLOYEE
WHERE INCOME > ?")
sth.execute(1000)
sth.fetch do |row|
printf "First Name: %s, Last Name : %s\n", row[0], row[1]
printf "Age: %d, Sex : %s\n", row[2], row[3]
printf "Salary :%d \n\n", row[4]
end
sth.finish
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
# 断开与服务器的连接
dbh.disconnect if dbh
end
다음 결과가 생성됩니다.
First Name: Mac, Last Name : Mohan
Age: 20, Sex : M
Salary :2000
First Name: John, Last Name : Poul
Age: 25, Sex : M
Salary :2300
데이터베이스에서 레코드를 가져오는 방법도 많이 있습니다. 관심이 있다면 Ruby DBI 읽기 작업을 확인해 보세요.
모든 데이터베이스에 대한 업데이트 작업은 데이터베이스에 있는 하나 이상의 기존 레코드를 업데이트하는 것을 의미합니다. 다음 예에서는 SEX가 'M'인 모든 레코드를 업데이트합니다. 여기서는 모든 남성의 연령에 1년을 추가하겠습니다. 이 작업은 세 단계로 수행됩니다.
필수 조건에 따라 SQL 쿼리를 준비합니다. 이 작업은 prepare 방법을 사용하여 수행됩니다.
SQL 쿼리를 실행하고 데이터베이스에서 모든 결과를 선택하세요. 이 작업은 execute 메서드를 사용하여 수행됩니다.
출시문 핸들. 이 작업은 finish 메서드를 사용하여 수행됩니다.
모든 것이 순조롭게 진행되면 해당 작업을 커밋하고, 그렇지 않으면 롤백하여 거래를 완료할 수 있습니다.
#!/usr/bin/ruby -w
require "dbi"
begin
# 连接到 MySQL 服务器
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare("UPDATE EMPLOYEE SET AGE = AGE + 1
WHERE SEX = ?")
sth.execute('M')
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# 断开与服务器的连接
dbh.disconnect if dbh
end
데이터베이스에서 레코드를 삭제하려면 DELETE 작업을 사용해야 합니다. 다음 예에서는 AGE가 20보다 큰 EMPLOYEE의 모든 레코드를 삭제합니다. 이 작업의 단계는 다음과 같습니다.
필수 조건에 따라 SQL 쿼리를 준비합니다. 이 작업은 prepare 방법을 사용하여 수행됩니다.
SQL 쿼리를 실행하여 데이터베이스에서 필요한 레코드를 삭제하세요. 이 작업은 execute 메서드를 사용하여 수행됩니다.
출시문 핸들. 이 작업은 finish 메서드를 사용하여 수행됩니다.
모든 것이 순조롭게 진행되면 해당 작업을 커밋하고, 그렇지 않으면 롤백하여 거래를 완료할 수 있습니다.
#!/usr/bin/ruby -w
require "dbi"
begin
# 连接到 MySQL 服务器
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare("DELETE FROM EMPLOYEE
WHERE AGE > ?")
sth.execute(20)
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# 断开与服务器的连接
dbh.disconnect if dbh
end
거래는 거래 일관성을 보장하는 메커니즘입니다. 트랜잭션에는 다음 네 가지 속성이 있어야 합니다.
원자성: 트랜잭션의 원자성은 트랜잭션에 포함된 프로그램이 데이터베이스의 논리적 작업 단위 역할을 하며 프로그램이 수행하는 모든 데이터 수정 작업은 다음 중 하나임을 의미합니다. 하세요, 아니면 전혀 하지 마세요.
일관성: 트랜잭션의 일관성은 트랜잭션이 실행되기 전후에 데이터베이스가 일관된 상태에 있어야 함을 의미합니다. 데이터베이스의 상태가 모든 무결성 제약 조건을 충족하면 데이터베이스는 일관성이 있다고 합니다.
격리: 트랜잭션의 격리는 동시 트랜잭션이 서로 격리된다는 것을 의미합니다. 즉, 트랜잭션 내의 작업과 작동 중인 데이터를 차단해야 하며 이를 수정하려는 다른 트랜잭션에서 볼 수 없습니다.
Durability(내구성): 트랜잭션의 내구성은 시스템 또는 미디어 오류가 발생할 때 커밋된 트랜잭션에 대한 업데이트가 손실되지 않도록 보장하는 것을 의미합니다. 즉, 트랜잭션이 커밋되면 데이터베이스의 데이터에 대한 변경 사항은 영구적이어야 하며 데이터베이스 시스템 오류를 견뎌야 합니다. 데이터베이스 백업 및 복구를 통해 내구성이 보장됩니다.
DBI는 트랜잭션을 실행하는 두 가지 방법을 제공합니다. 하나는 트랜잭션을 커밋하거나 롤백하는 데 사용되는 commit 또는 rollback 방법입니다. 트랜잭션을 구현하는 데 사용할 수 있는 transaction 메서드도 있습니다. 다음으로 트랜잭션을 구현하는 두 가지 간단한 방법을 소개하겠습니다.
방법 I
첫 번째 방법은 DBI의 commit 및 rollback 방법을 사용하여 트랜잭션을 명시적으로 커밋하거나 취소합니다.
dbh['AutoCommit'] = false # 设置自动提交为 false.
begin
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1
WHERE FIRST_NAME = 'John'")
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1
WHERE FIRST_NAME = 'Zara'")
dbh.commit
rescue
puts "transaction failed"
dbh.rollback
end
dbh['AutoCommit'] = true
방법 II
두 번째 방법은 transaction 방법. 이 방법은 트랜잭션을 구성하는 명령문이 포함된 코드 블록이 필요하기 때문에 비교적 간단합니다. transaction 메소드는 블록을 실행한 다음 블록이 성공적으로 실행되었는지 여부에 따라 자동으로 commit 또는 rollback을 호출합니다.
dbh['AutoCommit'] = false # 设置自动提交为 false
dbh.transaction do |dbh|
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1
WHERE FIRST_NAME = 'John'")
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1
WHERE FIRST_NAME = 'Zara'")
end
dbh['AutoCommit'] = true
Commit은 데이터베이스가 변경을 완료했음을 식별하는 작업입니다. 이 작업을 수행하면 모든 변경 사항을 되돌릴 수 없습니다.
다음은 commit 메소드를 호출하는 간단한 예입니다.
dbh.commit
하나 이상의 변경 사항이 만족스럽지 않고 이러한 변경 사항을 완전히 되돌리려면 rollback 방법을 사용하세요.
다음은 rollback 메소드를 호출하는 간단한 예입니다.
dbh.rollback
데이터베이스 연결을 끊어야 하는 경우 연결 끊기 API를 사용하세요.
dbh.disconnect
사용자가 연결 해제 방법을 통해 데이터베이스 연결을 닫으면 DBI는 모든 미해결 트랜잭션을 롤백합니다. 그러나 DBI 구현 세부 사항에 의존하지 않고도 커밋이나 롤백을 명시적으로 호출해도 애플리케이션이 문제가 없습니다.
오류의 원인은 다양합니다. 예를 들어, SQL 문을 실행할 때 구문 오류가 있거나, 연결이 실패하거나, 취소되거나 완료된 문 핸들에 대해 가져오기 메서드가 호출되는 경우입니다.
DBI 메소드가 실패하면 DBI는 예외를 발생시킵니다. DBI 메소드는 모든 유형의 예외를 발생시킬 수 있지만 가장 중요한 두 가지 예외 클래스는 DBI::InterfaceError 및 DBI::DatabaseError입니다.
이 클래스의 예외 개체에는 err, errstr 및 state의 세 가지 속성이 있습니다. 하위 테이블은 오류 번호, 설명 오류 문자열 및 표준 오류 코드를 나타냅니다. 속성은 다음과 같이 자세히 설명됩니다.
err: 발생한 오류의 정수 표현을 반환하거나 DBD가 지원하지 않는 경우 nil을 반환합니다. 예를 들어 Oracle DBD는 오류 메시지의 숫자 부분으로 ORA-XXXX를 반환합니다.
errstr: 발생한 오류에 대한 문자열 표현을 반환합니다.
state: 발생한 오류의 SQLSTATE 코드를 반환합니다. SQLSTATE는 5자 문자열입니다. 대부분의 DBD는 이를 지원하지 않으므로 nil이 반환됩니다.
위의 예에서 다음 코드를 확인했습니다.
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# 断开与服务器的连接
dbh.disconnect if dbh
end
스크립트가 실행될 때 실행 중인 내용에 대한 디버깅 정보를 얻으려면 추적을 활성화할 수 있습니다. 이렇게 하려면 먼저 dbi/trace 모듈을 다운로드한 다음 추적 모드와 출력 대상을 제어하는 trace 메서드를 호출해야 합니다.
require "dbi/trace"
..............
trace(mode, destination)
mode 값은 0(해제), 1, 2 또는 3일 수 있습니다. , 대상 값은 IO 개체여야 합니다. 기본값은 각각 2와 STDERR입니다.
에는 핸들을 생성하는 몇 가지 메서드가 있습니다. 이러한 메서드는 코드 블록을 통해 호출됩니다. 메소드와 함께 코드 블록을 사용하면 코드 블록에 핸들을 매개변수로 제공하여 블록이 종료되면 자동으로 지워진다는 장점이 있습니다. 다음은 이 개념을 이해하는 데 도움이 되는 몇 가지 예입니다.
DBI.connect: 이 메서드는 데이터베이스 핸들을 생성합니다. 블록 끝에서 disconnect를 호출하여 데이터베이스 연결을 끊는 것이 좋습니다.
dbh.prepare: 이 메소드는 명령문 핸들을 생성하며 블록 끝에서 finish를 호출하는 것이 좋습니다. 블록 내에서 execute 메서드를 호출하여 명령문을 실행해야 합니다.
dbh.execute: 이 메서드는 dbh.prepare와 유사하지만 dbh.execute는 블록 내에서 실행 메서드를 호출할 필요가 없습니다. 명령문 핸들이 자동으로 실행됩니다.
인스턴스 1
DBI.connect은 코드 블록을 가질 수 있고 이를 데이터베이스 핸들에 전달하면 블록 끝에서 핸들의 연결이 자동으로 끊어집니다.
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123") do |dbh|
인스턴스 2
dbh.prepare는 코드 블록을 가질 수 있고 여기에 명령문 핸들을 전달하면 블록 끝에서 자동으로 종료가 호출됩니다.
dbh.prepare("SHOW DATABASES") do |sth|
sth.execute
puts "Databases: " + sth.fetch_all.join(", ")
end
인스턴스 3
dbh.execute은 코드 블록을 가질 수 있고 여기에 명령문 핸들을 전달하면 블록 끝에서 자동으로 종료가 호출됩니다.
dbh.execute("SHOW DATABASES") do |sth|
puts "Databases: " + sth.fetch_all.join(", ")
end
DBI transaction 메소드에는 위 장에서 설명한 코드 블록도 있을 수 있습니다.
DBI를 사용하면 데이터베이스 드라이버가 추가 데이터베이스 관련 기능을 제공할 수 있습니다. 이 기능은 모든 Handle 개체의 func 메서드를 통해 사용자가 호출할 수 있습니다.
드라이버별 속성을 설정하거나 가져오려면 []= 또는 [] 메서드를 사용하세요.
DBD::Mysql은 다음과 같은 드라이버 관련 기능을 구현합니다.
일련 번호 | Function & Description |
---|
1 | dbh.func(:createdb, db_name) 새 데이터베이스 만들기 . |
2 | dbh.func(:dropdb, db_name) 데이터베이스를 삭제합니다. |
3 | dbh.func(:reload) 다시 로드 작업을 수행합니다. |
4 | dbh.func(:shutdown) 서버를 종료합니다. |
5 | dbh.func(:insert_id) => Fixnum 이 연결에 대한 가장 최근의 AUTO_INCREMENT 값을 반환합니다. |
6 | dbh.func(:client_info) => String 버전에 따른 MySQL 클라이언트 정보를 반환합니다. |
7 | dbh.func(:client_version) => Fixnum 버전에 따른 클라이언트 정보를 반환합니다. 이는 :client_info와 유사하지만 문자열 대신 수정 번호를 반환합니다. |
8 | dbh.func(:host_info) => String 호스트 정보를 반환합니다. |
9 | dbh.func(:proto_info) => Fixnum 통신에 사용되는 프로토콜을 반환합니다. |
10 | dbh.func(:server_info) => String 버전에 따른 MySQL 서버 측 정보를 반환합니다. |
11 | dbh.func(:stat) => Stringb> 데이터베이스의 현재 상태를 반환합니다. |
12 | dbh.func(:thread_id) => Fixnum 현재 스레드의 ID를 반환합니다. |
Instance
#!/usr/bin/ruby
require "dbi"
begin
# 连接到 MySQL 服务器
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
puts dbh.func(:client_info)
puts dbh.func(:client_version)
puts dbh.func(:host_info)
puts dbh.func(:proto_info)
puts dbh.func(:server_info)
puts dbh.func(:thread_id)
puts dbh.func(:stat)
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
dbh.disconnect if dbh
end
이 결과는 다음과 같습니다.
5.0.45
50045
Localhost via UNIX socket
10
5.0.45
150621
Uptime: 384981 Threads: 1 Questions: 1101078 Slow queries: 4 \
Opens: 324 Flush tables: 1 Open tables: 64 \
Queries per second avg: 2.860