2009-10-27 22 views
6

Je travaille dans un script R qui utilise une longue chaîne SQL, et je voudrais garder la requête relativement libre d'autres balisages afin de permettre la copie et le collage entre les éditeurs et les applications. J'aimerais aussi pouvoir diviser la requête entre les lignes pour une meilleure lisibilité.Puis-je inclure avec élégance des chaînes SQL formatées dans un script R?

Dans la documentation RODBC, la fonction paste est utilisée pour générer la requête à partir de blocs distincts, mais je préfère quelque chose de moins kludgy et avec moins de guillemets et de virgules. Merci de votre aide.

Répondre

7

vous pouvez remplacer le% +% opérateur d'avoir une meilleure chaîne concaténation syntaxe:

'%+%' <- function(x,y) paste(x,y,sep="") 

y<-"y1" 
x<-"somethingorother" 
query<- 
'SELECT DISTINCT x AS ' %+% x %+%',\n' %+% 
'    y AS ' %+% y %+% '\n' %+% 
' FROM tbl 
WHERE id=%s 
AND num=%d' 

cat(query,"\n") 

rendements:

> cat(query,"\n") 
SELECT DISTINCT x AS somethingorother, 
       y AS y1 
FROM tbl 
WHERE id=%s 
AND num=%d 
+0

J'aime le remplacement. Merci. –

+0

Je trouve shQuote utile lorsque x ou y sont des chaînes. –

11

Si vous êtes un ancien programmeur C de retour, comme je suis , vous pourriez aimer juste utiliser sprintf().

emprunt exemple de Ian:

y<-"y1" 
x<-"somethingorother" 
query <- sprintf(
'SELECT DISTINCT x AS %s, 
       y AS %s, 
FROM tbl 
WHERE id=%%s 
AND num=%%d', x, y) 

rendements:

> cat(query,"\n") 
SELECT DISTINCT x AS somethingorother, 
       y AS y1, 
FROM tbl 
WHERE id=%s 
AND num=%d 
+0

J'aime aussi utiliser sprintf pour interpoler dans des chaînes multi-lignes. Il rappelle toujours légèrement comment vous liez les variables aux instructions dans DBI de Perl. Et lisible. – medriscoll

1

J'ai fini par frapper simplement la chaîne sql avec sql <- gsub("\n","",sql) et sql <- gsub("\t","",sql) avant de l'exécuter. La chaîne elle-même peut être aussi longue qu'elle doit l'être, mais reste libre de tout balisage de concaténation.

3

Je vous recommande d'utiliser simplement une chaîne de caractères sans incruster des valeurs de variables. Utilisez des espaces réservés à la place.

sql <- "SELECT foo FROM bar 
    WHERE col1 = ? 
    AND col2 = ? 
    ORDER BY yomama" 

Je ne suis pas sûr si le guillemet est la meilleure façon d'intégrer les chaînes multi-lignes dans le code R (est là quelque chose comme ici-docs?), Mais il fonctionne, contrairement à Java.

Y a-t-il une raison pour laquelle vous ne voulez pas envoyer "\n" ou "\t" à votre base de données? Ils devraient être bien dans le SQL.

+1

Comment puis-je lier des valeurs à ces espaces réservés? Je n'ai rien trouvé dans la documentation de RODBC. –

+0

Certains pilotes semblent le soutenir, d'autres non. Voir http://stackoverflow.com/questions/2186015/bind-variables-in-r-dbi. –

+0

RODBC ne prend pas en charge les requêtes paramétrées. RODBCext ajoute ceci. On dirait que DBI est en train de les ajouter. – blongworth

5

Une manière gracieuse de "y compris" une longue requête SQL est de le conserver dans un fichier séparé .sql. De préférence, quelque part, il peut être mis en évidence, un fichier texte dans RStudio fera l'affaire. Vous pouvez ensuite, dans votre script R principal, lire le fichier dans une chaîne et le remplir avec des variables en utilisant l'une des nombreuses solutions de type "named" sprintf, telles que infuser.

.SQL

select * 
from mytable 
where id = {{a}} 
and somevar = {{b}} 

.R

library(readr) 
library(infuser) 

query <- read_file("query.sql") %>% 
     infuse(a = 1, b = 2) 
+0

Une instruction préparée est le moyen le plus sûr de le faire. –

+0

Une instruction préparée est également beaucoup plus efficace dans de nombreux cas. Si votre DB dispose d'un optimiseur de mise en cache, il peut utiliser le même plan d'exécution pour la même instruction avec divers paramètres liés, mais si vous substituez directement les paramètres au SQL, il devra probablement recalculer le plan à chaque fois. –