11

私は R と Knitr で RODBC を使用して、さまざまな実稼働データベースを使用してレポートを作成しています。これらのレポートのいくつかでは、複数のデータベースに対して複数のクエリを実行しています。

私のクエリはそれぞれ、次の形式の関数で実行されます。

get.total.orders <- function(db.connex.string, start.date, end.date){
    db.connex <- odbcDriverConnect(db.connex.string)
    ord.qry <- sprintf("SELECT ord_OrderReference AS 'order.ref',
ord_RegisterDate as 'register.date'
FROM Orders
WHERE ord_RegisterDate >= '%s' AND ord_RegisterDate < '%s'",
                       start.date, end.date)
    orders <- sqlQuery(db.connex, ord.qry)
    odbcClose(db.connex)
    return(orders)
}

ODBC チャネルはこの関数で開いたり閉じたりすることに注意してください。また、チャネルを開いたり閉じたりする間に実行されるクエリは 1 つだけであることに注意してください。

それにもかかわらず、レポートを複数回実行すると (レポートの作成時など)、次のような警告が表示されます。

Warning: closing unused RODBC handle 41

レポートを実行する回数が増えるほど、エラーで報告されるハンドルの数が多くなります。

クエリ関数でチャネルを開いたり閉じたりすると、「未使用」の RODBC ハンドルが開いたままになるのはなぜですか?

さらに重要なことに、この問題を回避するにはどうすればよいですか?

4

2 に答える 2

5

私は次のようにそれを避けますon.exit

get.total.orders <- function(db.connex.string, start.date, end.date){
   db.connex <- odbcDriverConnect(db.connex.string)
   on.exit(odbcClose(db.connex))  # <-----------------------   change here
   ord.qry <- sprintf("SELECT ord_OrderReference AS 'order.ref',
      ord_RegisterDate as 'register.date'
         FROM Orders
         WHERE ord_RegisterDate >= '%s' AND ord_RegisterDate < '%s'",
         start.date, end.date)
 orders <- sqlQuery(db.connex, ord.qry)
 return(orders)
 }

これにより、エラーが発生しても接続が閉じられます。も参照してください?on.exit

[編集]

上記は、クエリの実行中にエラーが発生したため、ハンドルが閉じられなかったことを前提としています。クエリは問題なかったが、ハンドルが閉じられていなかった場合、私にはわかりません。odbcClose成功した場合は 0 を返すので、それを確認してください。

[編集2]

他の人が指摘しているように、これはおそらく心配する必要はありません。一方で、明示的に閉じるように指示した場合、接続が閉じられない理由を理解することは依然として興味深いでしょう。おそらく数ミリ秒の問題であり、結果が割り当てられているときにクエリはまだ終了していません。結果が割り当てられているかのように、これは私にはあまり意味がありませんorders。データベースについて他に何がありますか? でも何かあるかも。その場合、もう少し時間をかけてみてください。

#...
orders <- sqlQuery(db.connex, ord.qry)
orders # or force(orders) - to just evaluate the result once more
Sys.sleep(0.01)  # give it 10 milliseconds
orders # or return(orders) - to return the result
# presuming on.exit as before - so odbcClose will happen here too
}

これは本当にばかげているように聞こえますが、実際に機能したとしてもそれほど驚くことではありません。

もう 1 つの考えは、Rstudio を使用している場合、たとえば、plot最初に存在しないグラフィカル パラメータを使用し、2 回目にエラーが発生しない場合などに、いくつかのファントム エラー メッセージが表示される可能性があることです。

plot(1, bimbo=2)  # here you get some warnings as bimbo is not a graphical parameter
plot(2)   # nothing wrong here but RStudio replays the previous warnings

db ハンドラーでも同様のことが発生する可能性があります。その場合は、RStudio とコンソール (Windows で Rgui または Rterm を実行するか、Linux のターミナルで R を実行するか) の両方で同じ警告が表示されるかどうかを確認することをお勧めします。もちろん、Rstudio を使用している場合にも当てはまります。

最後に、Brian Ripley (RODBC の作成者の 1 人) がここにはいるが、ここにはいないので、これを r-help に投稿してみてください。

ご覧のとおり、私には本当の答えがありません。それを理解するのに多大な労力がかかる場合は、心配しないことをお勧めします:)

于 2014-02-06T21:12:42.467 に答える
2

odbcClose()接続に開いているトランザクションがある場合、関数は失敗します。この場合、この接続は開いたままになります。

于 2013-09-04T19:00:00.107 に答える