2010-11-23 5 views
2

Ruby를 배우려는 시도에서 나는 Mr. Neighborly's Humble Little Ruby Book을 읽었습니다.왜 간단한 Ruby SQLite3 예제가 실패합니까?

대부분의 예는, 나에게 루비에 대한 좋은 소개를주는 따라 매우 쉽게되었습니다하지만 난 쉽게 DB 관련 예제를 실행할 수 없습니다.

이 코드를 실행하기 위해 노력하고있어

: 실행하면 (약간 책에서 주어진 예에서 수정)

#!/usr/bin/ruby 
require 'rubygems' 
require 'dbi' 

DBI.connect('DBI:SQLite3:testdb', 'ruby', 'ruby') do | dbh | 
    dbh.do('CREATE TABLE slugs(name varchar(20), age int);') rescue puts "TABLE slugs already exists." 

    sql = "INSERT INTO slugs (name, age) VALUES (?, ?)" 

    dbh.prepare(sql) do |st| 
    1.upto(20) do |i| 
     st.execute("slug #{i}", "#{i}") 
    end 
    end 

end 

, 그것은 데이터베이스에 하나 개의 행을 삽입은, 그것은 나에게 다음과 같은 오류를 제공합니다 :

 
/var/lib/gems/1.8/gems/sqlite3-ruby-1.3.2/lib/sqlite3/statement.rb:41:in `bind_param': library routine called out of sequence (SQLite3::MisuseException) 
    from /var/lib/gems/1.8/gems/sqlite3-ruby-1.3.2/lib/sqlite3/statement.rb:41:in `bind_params' 
    from /var/lib/gems/1.8/gems/sqlite3-ruby-1.3.2/lib/sqlite3/statement.rb:37:in `each' 
    from /var/lib/gems/1.8/gems/sqlite3-ruby-1.3.2/lib/sqlite3/statement.rb:37:in `bind_params' 
    from /var/lib/gems/1.8/gems/dbd-sqlite3-1.2.5/lib/dbd/sqlite3/statement.rb:71:in `bind_params' 
    from /var/lib/gems/1.8/gems/dbi-0.4.5/lib/dbi/handles/statement.rb:115:in `execute' 
    from /media/dev/ruby-prax/moi.rb:12 
    from /media/dev/ruby-prax/moi.rb:11:in `upto' 
    from /media/dev/ruby-prax/moi.rb:11 
    from /var/lib/gems/1.8/gems/dbi-0.4.5/lib/dbi/handles/database.rb:61:in `prepare' 
    from /media/dev/ruby-prax/moi.rb:10 
    from /var/lib/gems/1.8/gems/dbi-0.4.5/lib/dbi/handles/driver.rb:41:in `connect' 
    from /var/lib/gems/1.8/gems/dbi-0.4.5/lib/dbi.rb:148:in `connect' 
    from /media/dev/ruby-prax/moi.rb:5 
TABLE slugs already exists. 

나는 현재 우분투 10.04를 사용 중입니다. 버전 정보 :

 
[email protected]:/media/dev/ruby-prax$ ruby -v 
ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux] 
[email protected]:/media/dev/ruby-prax$ gem list 

*** LOCAL GEMS *** 

abstract (1.0.0) 
daemons (1.1.0) 
dbd-mysql (0.4.4) 
dbd-odbc (0.2.5) 
dbd-sqlite3 (1.2.5) 
dbi (0.4.5) 
deprecated (3.0.0, 2.0.1) 
erubis (2.6.6) 
eventmachine (0.12.10) 
extlib (0.9.15) 
json_pure (1.4.6) 
mysql (2.8.1) 
rack (1.2.1) 
sqlite3-ruby (1.3.2) 
thin (1.2.7) 
thor (0.14.1) 
[email protected]:/media/dev/ruby-prax$ sqlite3 --version 
3.6.22 
[email protected]:/media/dev/ruby-prax$ 

내가 뭘 잘못하고 있니?

slugs(name varchar(20), age int); 

하지만 당신은 삽입하려고 :

답변

1

테이블 정의는 정수가 아닌

st.execute("slug #{i}", "#{i}") 

"#{i}" 것을, 그것이 문자열입니다. 이 예와 같이 i으로 변경하십시오.

st.execute("slug #{i}", i) 

그런 다음 어떻게되는지보십시오.

+0

좋은 픽업! 그러나 그것을 바꾼 후에도 아무런 차이가 없었습니다. 나는 똑같은 행동을보고있다.사실 sqlite3의 경우 varchar 또는 int로 열을 정의하는지 여부에 관계없이이 간단한 삽입에 많은 차이가없는 것으로 보입니다. 나는 슬러그 (이름, 나이)를 시도했지만 여전히 같은 오류가 발생했습니다. –

+0

형식 불일치이기 때문에 "name"에 숫자를 전달하려고해도 같은 오류가 발생합니다. 이름은 문자열이어야하며 나이는 정수/고정 숫자 여야합니다. –

+0

테스트 중에 데이터베이스를 시작할 때 볼 수있는 또 다른 오류는 필드에 "고유"또는 "고유"절이있어 해당 필드를 고유 한 값으로 제한하는 것입니다. 순차 값을 삽입하려고 시도하는 코드를 다시 실행하면 DB가 미친 상태가되어 각 실행 전에 모든 행이 삭제됩니다. 그러나 "뚜렷한"절이있는 필드를 정의한 것으로 생각하지 않습니다. –

2

같은 문제가 발생했습니다. 준비된 INSERT 문을 두 번 이상 사용하면 DBD에 대한 SQLite 드라이버에 대해 issue on github이 발생합니다. Ruby/DBI는 더 이상 유지 관리되지 않으므로 개인적으로 RDBI으로 이동하는 것이 좋습니다. RDBI로 이동하는 데는 최소한의 코드 변경 만 필요했습니다.

+0

고마워, 내가 그것을 확인해 보겠습니다. –

0

은 어떻게 든 루비에 대한 몇 가지의 sqlite3를 라이브러리를 재설정하고 문 클래스에 대한 명확한 방법을 누락 생각합니다. 같은 SQL 문이 반복적으로 실행되면

는 성명 한 번 준비와 값의 새로운 세트로 실행됩니다. 그러나 명령문이 실행 된 후 다시 바인딩되기 전에 재설정해야합니다 (자주 지워짐). 핵심은 동일한 SQL을 반복해서 컴파일하고 최적화하는 것보다 사용 된 명령문을 재설정하는 것이 더 빠릅니다. 당신의 대부분은 아마이 모든 것을 알고 ...하지만 여기에 관련 부분의 SQLite는 문서에 대한 링크입니다 :

https://www.sqlite.org/c3ref/stmt.html

내가 다시 참조하지 않고 sqlite3를 :: 문 클래스의 명확한 방법, 그래서 이러한 어떻게 든이 구현에서 빠졌거나, 재사용 할 때 자동으로 재설정/제거 할 수있는 다른 메커니즘이 있지만 메커니즘이 어떻게 든 트리거되지 않습니다. 그러나, 심지어 문서에 언급되지 않은 ... 적어도 그것을 찾을 수 없습니다.

clear_bindings 및 재설정 방법이 SQLite3 :: Statement 클래스에서 누락되었다고 생각합니다.

https://github.com/sparklemotion/sqlite3-ruby/issues/158

관련 문제