2010-02-02 17 views
8

En el paquete de R DBI, no encuentro una posibilidad para usar variables enlazadas. Encontré un documento (la viñeta original de 2002) que dice sobre variables vinculadas, "Quizás DBI podría en algún momento en el futuro implementar esta característica", pero parece que hasta ahora no se ha hecho.Variables de enlace en R DBI

¿Qué utilizan las personas de R para un sustituto? ¿Simplemente concatenar cadenas directamente en el SQL? Eso tiene algunos problemas obvios para el rendimiento de seguridad &.

EDIT:

Aquí hay un ejemplo de cómo podrían trabajar marcadores de posición:

query <- "SELECT numlegs FROM animals WHERE color=?" 
result <- dbGetQuery(caseinfo, query, bind="green") 

Eso no es una interfaz muy bien pensada, pero la idea es que se puede utilizar un valor para bind y el controlador maneja los detalles del escape (si la API subyacente no maneja las variables enlazadas de forma nativa) sin que la persona que llama tenga que volver a implementarlo [mal].

+0

¿Puede proporcionar algún código de ejemplo que funcione como usted quisiera? ¿Qué comportamiento esperarías que tuvieran las variables vinculadas? –

+0

¿Te refieres a algo como esto? http://stackoverflow.com/questions/2182337/how-to-use-a-variable-name-in-a-mysql-statement –

+1

Huelo un nuevo DBI con mejores características. Todos seremos felices probadores beta, Ken ... –

Respuesta

16

Para cualquier persona Al llegar a esta pregunta, como acabo de hacer después de googlear para rsqlite y dbgetpreparedquery, parece que en la última versión de rsqlite puede ejecutar una consulta SELECT con variables de vinculación. Acabo de funcionar los siguientes:

query <- "SELECT probe_type,next_base,color_channel FROM probes WHERE probeid=?" 
probe.types.df <- dbGetPreparedQuery(con,que,bind.data=data.frame(probeids=ids)) 

Esto fue relativamente rápido (2.000 seleccionar filas de una tabla de 450.000 fila) y es increíblemente útil.

FYI.

+0

No estoy claro cuál es la diferencia entre dbgetpreparedquery y dbsendpreparedquery – Carbon

+1

Según tengo entendido, las funciones 'GetQuery' devuelven los resultados como un marco de datos, mientras que las funciones' SendQuery' devuelven un cursor desde el que puede solicitar resultados en lotes utilizando ' método fetch' Consulte la documentación de RSQLITE :: query http://cran.r-project.org/web/packages/RSQLite/RSQLite.pdf –

1

Hey hey - Acabo de descubrir que RSQLite, que es lo que estoy usando en este caso, en efecto, han soporte de variables con destino a:

http://cran.r-project.org/web/packages/RSQLite/NEWS

Véase la entrada sobre dbSendPreparedQuery() y dbGetPreparedQuery().

tanto, en teoría, que convierte esta maldad:

df <- data.frame() 
for (x in data$guid) { 
    query <- paste("SELECT uuid, cites, score FROM mytab WHERE uuid='", 
       x, "'", sep="") 
    df <- rbind(df, dbGetQuery(con, query)) 
} 

en esto:

df <- dbGetPreparedQuery(
    con, "SELECT uuid, cites, score FROM mytab WHERE uuid=:guid", data) 

Por desgracia, cuando realmente probarlo, parece que es sólo por INSERT declaraciones y similares, no para las declaraciones SELECT, porque me sale un error: RS-DBI driver: (cannot have bound parameters on a SELECT statement).

Proporcionar esa capacidad sería fantástico.

El siguiente paso sería elevar esto hasta DBI para que todos los DB puedan aprovecharlo, y proporcionar una implementación predeterminada que simplemente pegue en la cadena como todos nos estamos haciendo ahora.

3

A continuación se muestra un resumen de lo que actualmente admite RSQLite para los parámetros enlazados . Tiene razón en que actualmente no hay soporte para SELECT, pero no hay una buena razón para esto y me gustaría agregar soporte para .

Si se siente como la piratería, se puede conseguir una salida de sólo lectura de todos los paquetes relacionados DBI aquí:

use --user=readonly --password=readonly 

https://hedgehog.fhcrc.org/compbio/r-dbi/trunk 
https://hedgehog.fhcrc.org/compbio/r-dbi/trunk/DBI 
https://hedgehog.fhcrc.org/compbio/r-dbi/trunk/SQLite/RSQLite 

me gustaría recibir parches, especialmente si incluyen pruebas y documentación. Diff unificado, por favor.De hecho, me hago todo mi desarrollo utilizando git y así mejor de los casos es crear un clon de git de decir RSQLite y luego me enviar diferencias como git format-patch -n git-svn..

De todos modos, aquí hay algunos ejemplos:

library("RSQLite") 

make_data <- function(n) 
{ 
    alpha <- c(letters, as.character(0:9)) 
    make_key <- function(n) 
    { 
     paste(sample(alpha, n, replace = TRUE), collapse = "") 
    } 
    keys <- sapply(sample(1:5, replace=TRUE), function(x) make_key(x)) 
    counts <- sample(seq_len(1e4), n, replace = TRUE) 
    data.frame(key = keys, count = counts, stringsAsFactors = FALSE) 
} 

key_counts <- make_data(100) 


db <- dbConnect(SQLite(), dbname = ":memory:") 

sql <- " 
create table keys (key text, count integer) 
" 

dbGetQuery(db, sql) 

bulk_insert <- function(sql, key_counts) 
{ 
    dbBeginTransaction(db) 
    dbGetPreparedQuery(db, sql, bind.data = key_counts) 
    dbCommit(db) 
    dbGetQuery(db, "select count(*) from keys")[[1]] 
} 

## for all styles, you can have up to 999 parameters 

## anonymous 
sql <- "insert into keys values (?, ?)" 
bulk_insert(sql, key_counts) 


## named w/ :, $, @ 
## names are matched against column names of bind.data 

sql <- "insert into keys values (:key, :count)" 
bulk_insert(sql, key_counts[ , 2:1]) 

sql <- "insert into keys values ($key, $count)" 
bulk_insert(sql, key_counts) 

sql <- "insert into keys values (@key, @count)" 
bulk_insert(sql, key_counts) 

## indexed (NOT CURRENTLY SUPPORTED) 
## sql <- "insert into keys values (?1, ?2)" 
## bulk_insert(sql) 
Cuestiones relacionadas