加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl DBI – 运行带有多个语句的SQL脚本

发布时间:2020-12-15 21:16:22 所属栏目:大数据 来源:网络整理
导读:我有一个sql文件test.sql用于运行一些SQL(创建对象/更新/删除/插入),看起来像这样 CREATE TABLE test_dbi1 ( test_dbi_intr_no NUMBER(15),test_dbi_name VARCHAR2(100);UPDATE mytable SET col1=1; CREATE TABLE test_dbi2 ( test_dbi_intr_no NUMBER(15),t
我有一个sql文件test.sql用于运行一些SQL(创建对象/更新/删除/插入),看起来像这样
CREATE TABLE test_dbi1 (
    test_dbi_intr_no    NUMBER(15),test_dbi_name       VARCHAR2(100);

UPDATE mytable 
SET col1=1;

    CREATE TABLE test_dbi2 (
    test_dbi_intr_no    NUMBER(15),test_dbi_name       VARCHAR2(100);

通常,我只使用SQLPLUS(在Perl中)使用此命令执行此test.sql:
@ TEST.SQL

有没有办法在Perl中使用DBI做同样的事情?
到目前为止,我发现DBI一次只能执行一个语句,而没有“;”最后.

解决方法

数据库控制一次可以执行的语句数.我不记得Oracle是否允许每次准备多个语句(MySQL确实如此).尝试这个:
my $dbh = DBI->connect(
    "dbi:Oracle:dbname","username","password",{
        ChopBlanks       => 1,AutoCommit       => 1,RaiseError       => 1,PrintError       => 1,FetchHashKeyName => 'NAME_lc',}
);
$dbh->do("
    CREATE TABLE test_dbi1 (
        test_dbi_intr_no    NUMBER(15),test_dbi_name       VARCHAR2(100)
    );

    UPDATE mytable 
        SET col1=1;

    CREATE TABLE test_dbi2 (
        test_dbi_intr_no    NUMBER(15),test_dbi_name       VARCHAR2(100)
    );
");

$dbh->disconnect;

当然,如果你破坏语句,你会得到更好的错误处理.您可以使用简单的解析器将字符串分解为单个语句:

#!/usr/bin/perl

use strict;
use warnings;

my $sql = "
    CREATE TABLE test_dbi1 (
        test_dbi_intr_no    NUMBER(15),test_dbi_name       VARCHAR2(100)
    );

    UPDATE mytable
        SET col1=';yes;'
        WHERE col2=1;

    UPDATE mytable
        SET col1='Don't use ;s and 's together,it is a pain'
        WHERE col2=1;


    CREATE TABLE test_dbi2 (
        test_dbi_intr_no    NUMBER(15),test_dbi_name       VARCHAR2(100)
    );
";

my @statements = ("");
#split the string into interesting pieces (i.e. tokens):
#   ' delimits strings
#    pass on the next character if inside a string
#   ; delimits statements unless it is in a string
#   and anything else
# NOTE: the grep { ord } is to get rid of the nul
# characters the split seems to be adding
my @tokens     = grep { ord } split /([';])/,$sql; 
# NOTE: this ' fixes the stupid SO syntax highlighter
#this is true if we are in a string and should ignore ; 
my $in_string  = 0;
my $escape     = 0;
#while there are still tokens to process
while (@tokens) {
    #grab the next token
    my $token = shift @tokens;
    #if we are in a string
    if ($in_string) {
        #add the token to the last statement
        $statements[-1] .= $token;
        #setup the escape if the token is 
        if ($token eq "") {
                $escape = 1;
                next;
        }
        #turn off $in_string if the token is ' and it isn't escaped
        $in_string = 0 if not $escape and $token eq "'";
        $escape = 0; #turn off escape if it was on
        #loop again to get the next token

        next;
    }
    #if the token is ; and we aren't in a string
    if ($token eq ';') {
        #create a new statement
        push @statements,"";
        #loop again to get the next token
        next;
    }
    #add the token to the last statement
    $statements[-1] .= $token;
    #if the token is ' then turn on $in_string
    $in_string = 1 if $token eq "'";
}
#only keep statements that are not blank
@statements = grep { /S/ } @statements;

for my $i (0 .. $#statements) {
    print "statement $i:n$statements[$i]nn";
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读