2010-11-18 11 views
5

Nous avons un script Perl qui exécute un SQL et met des données dans la table. Maintenant, au lieu de fournir une seule instruction SQL, nous voulons en passer un tas en les regroupant dans un fichier .sql. Nous savons que notre programme échouera parce qu'il attend une seule instruction SQL, et non pas un tas d'entre eux (cela aussi à partir d'un fichier .sql). Comment pouvons-nous le faire fonctionner avec un fichier .sql (ayant plusieurs instructions INSERT?). Nous utilisons le paquet DBI.Exécuter le fichier SQL en Perl

Un petit bout de code:

$sth = $dbh->prepare("/home/user1/tools/mytest.sql"); 
$sth->execute || warn "Couldn't execute statement"; 
$sth->finish(); 
+0

Voir aussi http://stackoverflow.com/questions/945584/is-it-possible-to-execute-multiple-statements-in-a-single-query-using-dbdoracle http://stackoverflow.com/ questions/1232950/perl-dbi-run-sql-script-with-multiple-déclarations – daxim

Répondre

4

Pas exactement ce que vous voulez ...

Une fois que vous créez un objet DBI, vous pouvez utilisez-le encore et encore. Ici, je lis instruction SQL après instruction SQL à partir d'un fichier et de traitement de chacun afin:

use DBI; 

my $sqlFile = "/home/user1/tools/mytest.sql" 

my $dbh = DBI::Connect->new($connect, $user, $password) 
    or die("Can't access db"); 

# Open the file that contains the various SQL statements 
# Assuming one SQL statement per line 

open (SQL, "$sqlFile") 
    or die("Can't open file $sqlFile for reading"); 

# Loop though the SQL file and execute each and every one. 
while (my $sqlStatement = <SQL>) { 
    $sth = dbi->prepare($sqlStatement) 
     or die("Can't prepare $sqlStatement"); 

    $sth->execute() 
     or die("Can't execute $sqlStatement"); 
} 

Notez que je suis en train de l'instruction SQL dans le prepare et non le nom du fichier qui contient le SQL déclaration. Cela pourrait-il être votre problème?

+0

ici j'appelle le fichier dq.sql dans le script perl dans lequel je passe une variable comme $ nom_patch, $ svn_url, $ ftp_path qui est défini dans le fichier perl mais le fichier db.sql n'accède pas à ces variables? pls m'aidera dès que possible. »$ sqlfile =" C: /BuildScript/YellowBox_Script/YellowBox_Core_Script/db.sql "; open (SQL," $ sqlfile ") ou die (" Impossible d'ouvrir le fichier $ sqlFile pour la lecture "); while ($ instructionSQL = ) { $ sth = $ dbh-> prepare (instructionSQL $) or die ("Impossible de préparer instructionSQL $"); $ Sth-> execute() ou die ("Impossible d'exécuter $ sqlStatement"); } ' – picnic4u

+1

@ picnic4u: Pouvez-vous créer une question à la place d'un commentaire? D'autres le verront et pourront vous aider. –

+0

À moins de manquer quelque chose, cela suppose une déclaration par ligne, ce qui n'est guère garanti. –

4

Vous n'avez pas besoin perl pour cela du tout. Il suffit d'utiliser le client de ligne de commande mysql:

mysql -h [hostname] -u[username] -p[password] [database name] < /home/user1/tools/mytest.sql

remplacer les [les variables] avec vos informations.

Remarque aucun espace après -u ou -p. Si votre serveur MySQL est en cours d'exécution sur la même machine, vous pouvez omettre -h [nom d'hôte] (valeur par défaut localhost)

+0

Salut Cfreak, en fait C'est un script qui ne contient pas beaucoup d'autres choses, donc nous avons besoin de la modification est ce script. Merci pour la solution cependant. – t0mcat

0

Voici comment je l'ai fait. Dans mon cas, je ne suppose pas un SQL par ligne et je suppose, mon exemple est un peu mieux :)

sub get_sql_from_file { 
    open my $fh, '<', shift or die "Can't open SQL File for reading: $!"; 
    local $/; 
    return <$fh>; 
}; 

my $SQL = get_sql_from_file("SQL/file_which_holds_sql_statements.sql"); 
my $sth1 = $dbh1->prepare($SQL); 
$sth1->execute(); 
+1

Pourquoi 'get_sql_from_file' ne retournerait-il pas le code SQL plutôt que de définir une variable globale? Les variables globales sont mauvaises. –

+0

Il pourrait retourner le SQL, mais pourquoi pensez-vous que l'utilisation de la variable $ SQL est mauvaise dans cet exemple? Pouvez-vous l'expliquer? vouliez-vous dire que l'utilisation de variables globales est une mauvaise idée en général? –

+1

Les variables globales sont, en général, une mauvaise idée. Vos fonctions seront plus faciles à réutiliser si elles sont autonomes et ne supposent pas l'existence de variables externes. –

3

Il existe une sorte de solution de contournement pour DDL. Vous devez d'abord slurp le fichier SQL, puis inclure son contenu dans les mots-clés BEGIN ... END;. Comme:

sub exec_sql_file { 
    my ($dbh, $file) = @_; 

    my $sql = do { 
     open my $fh, '<', $file or die "Can't open $file: $!"; 
     local $/; 
     <$fh> 
    }; 

    $dbh->do("BEGIN $sql END;"); 
} 

Ce sous-programme permet d'exécuter des scripts DDL (SQL) avec plusieurs instructions à l'intérieur (par exemple la base de données dépotoirs).

Questions connexes