2009-10-27 6 views
6

Ich arbeite in einem R-Skript, das eine lange SQL-Zeichenfolge verwendet, und ich möchte die Abfrage relativ frei von anderen Markup, um Kopieren und Einfügen zwischen Editoren und Anwendungen zu ermöglichen. Ich möchte auch die Fähigkeit, die Abfrage für bessere Lesbarkeit über mehrere Zeilen zu teilen.Kann ich formatierte SQL-Zeichenfolgen in einem R-Skript enthalten?

In der RODBC-Dokumentation wird die paste-Funktion verwendet, um die Abfrage aus separaten Blöcken zu erstellen, aber ich würde etwas weniger kludgy und mit weniger Anführungszeichen und Kommas bevorzugen. Danke für Ihre Hilfe.

Antwort

7

Sie das% +% Operator überschreiben können besser Zeichenfolge Verketten Syntax zu haben:

'%+%' <- 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") 

ergibt:

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

Ich mag die Überschreibung. Vielen Dank. –

+0

Ich finde shQuote hilfreich, wenn x oder y Strings sind. –

11

Wenn Sie einen alten C-Programmierer aus Weg zurück sind, wie ich bin , könnte es Ihnen Spaß machen, einfach sprintf() zu benutzen.

Borrowing Ians Beispiel:

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

ergibt:

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

Ich mag auch Sprintf zum Interpolieren innerhalb mehrzeiliger Strings. Es erinnert immer wieder daran, wie Sie Variablen an Anweisungen in Perls DBI binden. Und lesbar. – medriscoll

1

Ich habe einfach die SQL-Zeichenfolge mit sql <- gsub("\n","",sql) Schlagen endete und sql <- gsub("\t","",sql), bevor es ausgeführt wird. Die Zeichenfolge selbst kann so lang sein, wie sie sein muss, aber sie bleibt frei von allen Verkettungsmarkierungen.

3

Ich würde empfehlen, nur eine einfache Zeichenfolge zu verwenden und keine Variablenwerte einzubetten. Verwenden Sie stattdessen Platzhalter.

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

Ich bin mir nicht sicher, ob das doppelte Anführungszeichen ist der beste Weg, mehrzeiligen Strings in R-Code zum Einbetten (gibt es so etwas wie hier-docs?), Aber es funktioniert, anders als in Java.

Gibt es einen Grund, warum Sie keine "\n" oder "\t" an Ihre Datenbank senden möchten? Sie sollten in der SQL in Ordnung sein.

+1

Wie kann ich Werte an diese Platzhalter binden? Ich konnte in der Dokumentation von RODBC nichts finden. –

+0

Einige Treiber scheinen es zu unterstützen, andere nicht. Siehe http://stackoverflow.com/questions/2186015/bind-variables-in-r-dbi. –

+0

RODBC unterstützt keine parametrisierten Abfragen. RODBCext fügt dies hinzu. Es hört sich an, als ob DBI sie gerade hinzufügt. – blongworth

5

Ein graziöser Weg "einschließlich" eine lange SQL-Abfrage ist es in einer separaten .sql Datei zu halten. Vorzugsweise kann irgendwo eine Syntax hervorgehoben werden, eine Textdatei in RStudio erledigt die Aufgabe. Sie können dann in Ihrem Haupt-R-Skript die Datei in eine Zeichenfolge lesen und sie mit Variablen auffüllen, indem Sie eine der vielen "benannten" sprintf-Typ-Lösungen verwenden, beispielsweise 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

Eine vorbereitete Anweisung ist der sicherere Weg, dies zu tun. –

+0

Eine vorbereitete Aussage ist in vielen Fällen auch viel effizienter. Wenn Ihre Datenbank über einen Caching-Optimierer verfügt, kann sie denselben Ausführungsplan für dieselbe Anweisung mit verschiedenen gebundenen Parametern verwenden. Wenn Sie jedoch die Parameter direkt in SQL ersetzen, muss der Plan wahrscheinlich jedes Mal neu berechnet werden. –

Verwandte Themen