2012-09-22 4 views
10

Ich muss eine Datei analysieren, um einzelne SQL-Anweisungen abzurufen und sie vom Rails-Controller auszuführen.Getrennte Zeichenfolge ohne Entfernen des Trennzeichens

Ich habe den folgenden Code:

@sql_file = "#{RAILS_ROOT}/lib/evidence_interface_import.sql" 
@sql_stmts_array = File.read(@sql_file).split(";") 

@sql_stmts_array.each_with_index do |sql_stmt,s_index| 
    ActiveRecord::Base.connection.execute(sql_stmt) 
end 

Die Spaltung entfernt das ";" vom Ende der SQLs. Gibt es eine Möglichkeit, das ";" und spalte immer noch mit ";".

Antwort

3

Das funktioniert (zum Beispiel select * from stuff where name = ";";.):

@sql_stmts_array = File.read(@sql_file).lines(separator=';') 
+1

Die Syntax ist falsch für' lines (separator ='; ') '- das funktioniert, aber es ist schlecht geschrieben. Es sollte stattdessen 'lines (';')' sein. Verwenden Sie 'File.readlines (@sql_file, ';')' stattdessen, weil es kürzer ist und dasselbe erreicht. –

1

Sie könnten versuchen, scan mit einem geeigneten Regex, die Ergebnisse ähnlich wie split geben, aber wenn Sie auf eine Weise ohne Regex bleiben möchten, können Sie einfach ein Semikolon an jede Zelle im Array anhängen:

@sql_stmts_array = File.read(@sql_file).split(";").each do |s| 
    s << ";" 
end 
+2

Dies hat einen Nebeneffekt ein Semikolon nach dem letzten Eintrag setzen. – willglynn

+1

Ist das nicht gewollt? Sollte nach jedem Eintrag kein '' 'stehen? – siame

13

Yup, scan es:

'a; b; c;'.scan(/[^;]*;/) 
#=> ["a;", " b;", " c;"] 

Sie die überschüssigen Leerzeichen bekommen konnten befreien, indem Anheften auf map(&:strip) nach, aber es ist wahrscheinlich hier nicht benötigt.

Beachten Sie, dass dies sehr rudimentär ist, und etwas wie ein String-Literal in der SQL mit einem Semikolon darin wird dies brechen.

+1

Eine ähnliche Option wäre: ''a; b; c; '. scan (/.*?;/) ' – Sajjad

3

Verwenden Sie einen regulären Ausdruck mit einem Lookbehind

split(/(?<=;)/) 
6

Wenn ActiveRecord::Base.connection.execute verwenden Sie nicht brauchen, um das Semikolon in erster Linie sind.

Auch eine andere Art und Weise, ohne dass der Begrenzer zu teilen ist es, Gruppen zu verwenden, wie im folgenden Beispiel gezeigt:

"a;b;c".split(/;/) # => ["a", "b", "c"] 

"a;b;c".split(/(;)/) # => ["a", ";", "b", ";", "c"] 
+1

für viele Fälle mit Tokenisierung und String-Manipulation - das ist eine großartige Lösung. –

+0

Ich würde dies als die akzeptierte Antwort markieren. 'scan' scheint nach jedem Element das Trennzeichen zu benötigen, nicht nur zwischen ihnen. –

Verwandte Themen