2017-06-26 8 views
-1

Ich habe viele lange SQL-Dateien, die eine Reihe von diskreten SQL-Befehle enthalten. Im Grunde fallen die Dateien und erstellen dann eine Reihe gespeicherter Prozeduren mit einigen Änderungen neu.Perl Parsing für SQL-Skripte

Ich muss sie analysieren, um die einzelnen drop/create scrips zu bekommen.

Perl ist meine erste Wahl, da es bei Parsing gut ist ... aber ich bin mit Perl nicht sehr erfahren ...

Hier ist, was ich bisher haben (man beachte ich im Wesentlichen wieder schrieb meiner ursprünglichen Versuch):

#!/usr/bin/perl 
use strict; 
use warnings; 

my $use = ""; 
my $use = "USE mydatabase;"; 

undef $/;    # Enable 'slurp' mode 
open my $fh, '<', 'AlterSprocs.sql' or die; 
$/= 'DROP PROCEDURE'; 
while (my $row = <$fh>) { 
$n ++; 
$row = $use . "\n" . "GO" . "\n" . 'DROP PROCEDURE' . $row . ';'; 
my $find = 'DROP PROCEDURE;'; 
my $replace = ""; 
$row =~ s/$find/$replace/g; 

open (MYFILE, '>', $n); 
print MYFILE $row; 
close (MYFILE); 

Der Text, den ich sieht aus wie etwas bin Parsen:

Use mydatabase; 
GO 
Drop Procedure [blah1] 
Create Procedure [blah1] 
[Sql stuff] 

Drop Procedure [blah2] 
Create Procedure [blah2] 
[Sql stuff] 

[repeat blah3....blah4...etc...etc..] 

Das gibt mir 1 benannten Dateien, 2, 3, usw. mit den diskreten gespeicherten Prozeduren in ihnen. Ich musste einige seltsame Zusätze hinzufügen und durch den Text ersetzen, um es richtig zu machen ... aber es funktioniert. Die letzte Datei wird mit einem zusätzlichen ";" aber ... das sollte sicher sein.

Das Hauptproblem, das ich jetzt habe, ist, dass die erste Datei leer ist wegen der Art, wie ich in "Drop Procedure" analysiere. Ich habe versucht, damit umzugehen, indem ich ein if/else in die while-Schleife einfügte, die nichts nützen würde, wenn n = 0 außer n ++;

if ($n = 0) 
{$n++;} 
else {all the other stuff I actually want to do} 

, aber dies erstellt nur eine Datei (mit dem Namen 1).

Ich muss immer noch den Namen der gespeicherten Prozedur herausziehen, damit ich die Ausgabedateien anstelle von $ n benennen kann, aber ich denke, dass das etwas geradlinig sein wird, da es die erste Zeile ist. Diese Massagen

#!/usr/bin/perl 
use strict; 
use warnings; 


my $file_name = ""; 
my $first_line = ""; 

undef $/;    # Enable 'slurp' mode 

open my $fh, '<', 'AlterSprocs.sql' or die; 


$/= 'DROP PROCEDURE'; 
while (my $row = <$fh>) { 

{ 
$n ++; 
if ($row =~ /\[dbo].\[(.*?)\]/) 
{ 
$file_name = $1; 
$row = 'DROP PROCEDURE' . $row . ';'; 
my $find = 'DROP PROCEDURE;'; 
my $replace = ""; 
$row =~ s/$find/$replace/g; 
$first_line = 'IF EXISTS (SELECT 1 FROM sysobjects with(nolock) WHERE id = OBJECT_ID(N\'[dbo].[' . $file_name . ']\'))' . "\n"; 
open (MYFILE, '>', "dbo." . $file_name . ".prc"); 
print MYFILE $first_line; 
print MYFILE $row; 
close (MYFILE); 
} 
} 

close $fh or die "Could not close sample.txt: $!"; 

die einzelnen Dateien, die es schafft, in ein Format, das von unserem automatisierten sproc Testamentsvollstrecker mag und benennt die Dateien nach dem sprocs in Frage:

+0

Es scheint keine Möglichkeit zu geben, die Ausgabe zu erhalten, die Sie aus dem in Ihrem Beitrag enthaltenen Skript anzeigen. –

+0

Perl kann nur gut parsen, wenn Sie Perl kennen! Ansonsten sind Sie wahrscheinlich produktiver in einer Sprache, die Sie besser kennen. –

+1

Ich sehe nicht einmal einen Versuch, mehrere Übereinstimmungen zu wiederholen. –

Antwort

0

landete ich mit einer ziemlich anderen Lösung, von wo ich angefangen hat.

+0

'$ row = 'DROP PROCEDURE'. $ Zeile. ';' # Stellen Sie sicher, dass die Prozedur DROP PROCEDURE IN $ row = ~ s/DROP PROCEDURE // g; # Wir wollen nicht, dass die Regex hungrig wird – bytepusher