perl变量到模块

perl变量到模块,perl,perl-module,Perl,Perl Module,我试图执行一个存储在模块中的查询,但该查询包含一些从主文件读取的变量,因此无法工作 在模块内无法访问主文件中的变量(其为空) 代码如下: sql.pm package sql; use parent 'Exporter'; our @EXPORT = qw(%query); our %query = ( one => "SELECT isnull(BusinessEntityID, '') as BusinessEntityID, isnull(Title,

我试图执行一个存储在模块中的查询,但该查询包含一些从主文件读取的变量,因此无法工作

在模块内无法访问主文件中的变量(其为空)

代码如下:

sql.pm

package sql;

use parent 'Exporter'; 

our @EXPORT = qw(%query);

our %query = (
    one => "SELECT isnull(BusinessEntityID, '') as BusinessEntityID,
       isnull(Title, '') as Title,
       isnull(FirstName, '') as FirstName,
       isnull(LastName, '') as LastName,
       isnull(Suffix, '') as Suffix,
       isnull(JobTitle, '') as JobTitle

FROM HumanResources.vEmployee
where BusinessEntityID = ".$id."
order by BusinessEntityID"

);

1;
main.pl

use strict;
use warnings;

use sql;

my $id = 273;
my $query_main = "$query{one}";

print $query_main;
这将使用where BusinessEntityID=而不是where BusinessEntityID=273打印查询


谢谢大家!

sql
包的作用域中没有词法
$id
变量,因此它被评估为
unde
,并被字符串化为空字符串

当您尝试运行程序时,您将看到警告消息。请不要忽视它们,尤其是当你请求帮助时:它们非常重要

请合理命名您的模块。类似于
sql
的名称表示pragma,并影响以下所有代码。一个模块将使用
大写::字母
,并且应该与CPAN中的任何内容都非常不同

我认为应该将库限制为仅包含常量的子例程,并且应该避免在SQL查询字符串中插入值

比如说

package My::Sql;

use Exporter 'import';

our @EXPORT = qw/
    QUERY_ONE
/;

use constant {
    QUERY_ONE => "SELECT isnull(BusinessEntityID, '') as BusinessEntityID,
       isnull(Title, '') as Title,
       isnull(FirstName, '') as FirstName,
       isnull(LastName, '') as LastName,
       isnull(Suffix, '') as Suffix,
       isnull(JobTitle, '') as JobTitle

FROM HumanResources.vEmployee
where BusinessEntityID = ?
order by BusinessEntityID"

);

1;
如果你

use My::Sql;

my $sth = $dbh->prepare(QUERY_ONE);
$sth->execute(42);

那么您的代码至少应该能够正常工作,但是设计仍然非常缺乏

sql
包的范围内没有词法
$id
变量,因此它被评估为
unde
,并被字符串化为空字符串

当您尝试运行程序时,您将看到警告消息。请不要忽视它们,尤其是当你请求帮助时:它们非常重要

请合理命名您的模块。类似于
sql
的名称表示pragma,并影响以下所有代码。一个模块将使用
大写::字母
,并且应该与CPAN中的任何内容都非常不同

我认为应该将库限制为仅包含常量的子例程,并且应该避免在SQL查询字符串中插入值

比如说

package My::Sql;

use Exporter 'import';

our @EXPORT = qw/
    QUERY_ONE
/;

use constant {
    QUERY_ONE => "SELECT isnull(BusinessEntityID, '') as BusinessEntityID,
       isnull(Title, '') as Title,
       isnull(FirstName, '') as FirstName,
       isnull(LastName, '') as LastName,
       isnull(Suffix, '') as Suffix,
       isnull(JobTitle, '') as JobTitle

FROM HumanResources.vEmployee
where BusinessEntityID = ?
order by BusinessEntityID"

);

1;
如果你

use My::Sql;

my $sth = $dbh->prepare(QUERY_ONE);
$sth->execute(42);

那么,您的代码至少应该可以正常工作,但设计仍然非常缺乏

当然,在Perl中,可以从另一个包访问包的全局变量。
但这意味着您必须将所有
local
my
变量转换为全局变量。
这将是一片混乱。
我强烈建议不要那样做

简化占位符变量管理的方法之一是使用模板工具包,如下所示:

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

my $template = <<'CUT';
SELECT isnull(BusinessEntityID, '') as BusinessEntityID,
       isnull(Title, '') as Title,
       isnull(FirstName, '') as FirstName,
       isnull(LastName, '') as LastName,
       isnull(Suffix, '') as Suffix,
       isnull(JobTitle, '') as JobTitle

FROM HumanResources.vEmployee
where BusinessEntityID = [% id %]
order by BusinessEntityID
CUT
;

my $id=100;
my ($param1,$paramN);
my $vars = {
    'id'=>$id,
    'param1'=>$param1,
     #...
    'paramN'=>$paramN,
};

my $tp = Template->new();
my $out;
$tp->process(\$template, $vars, \$out)
    || die $template->error();
print($out);

但是,如果要使用不同的参数多次运行同一查询,则应使用Borodin回答中所示的参数绑定,以避免性能损失。

当然,在Perl中,可以从另一个包访问包的全局变量。
但这意味着您必须将所有
local
my
变量转换为全局变量。
这将是一片混乱。
我强烈建议不要那样做

简化占位符变量管理的方法之一是使用模板工具包,如下所示:

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

my $template = <<'CUT';
SELECT isnull(BusinessEntityID, '') as BusinessEntityID,
       isnull(Title, '') as Title,
       isnull(FirstName, '') as FirstName,
       isnull(LastName, '') as LastName,
       isnull(Suffix, '') as Suffix,
       isnull(JobTitle, '') as JobTitle

FROM HumanResources.vEmployee
where BusinessEntityID = [% id %]
order by BusinessEntityID
CUT
;

my $id=100;
my ($param1,$paramN);
my $vars = {
    'id'=>$id,
    'param1'=>$param1,
     #...
    'paramN'=>$paramN,
};

my $tp = Template->new();
my $out;
$tp->process(\$template, $vars, \$out)
    || die $template->error();
print($out);

但是,如果要使用不同的参数多次运行同一查询,则应使用Borodin回答中所示的参数绑定,以避免性能损失。

在sql包内部创建一个函数
get_query{my($id)=@;%query=…}
。调用它
my$query\u main=sql::get\u query($id)请阅读并使用占位符,而不是直接在查询中插入变量。@wolfrevokcats感谢您的快速回复,这很有帮助,但我还有更多(50+)依赖于各种foreach/ifs等。是否有更简单的方法,而不必声明模块中的每个变量?我在想是否有可能从main.pl导出所有变量并将它们导入sql。pm@rooger全局变量几乎总是一个坏主意。你会失去对它的控制。在我的几份工作中,我不得不与使用全局变量的现有程序进行大量斗争。如果有许多变量,则应使用哈希并将其传递给least@tinita谢谢你的快速回复,如果可能的话,你能给我一个简单的例子吗?在sql包中创建一个函数
get_query{my($id)=@;%query=…}
。调用它
my$query\u main=sql::get\u query($id)请阅读并使用占位符,而不是直接在查询中插入变量。@wolfrevokcats感谢您的快速回复,这很有帮助,但我还有更多(50+)依赖于各种foreach/ifs等。是否有更简单的方法,而不必声明模块中的每个变量?我在想是否有可能从main.pl导出所有变量并将它们导入sql。pm@rooger全局变量几乎总是一个坏主意。你会失去对它的控制。在我的几份工作中,我不得不与使用全局变量的现有程序进行大量斗争。如果有许多变量,则应使用哈希并将其传递给least@tinita谢谢你的快速回复,如果可能的话,你能给我一个简单的例子吗?谢谢,我会这样做的!谢谢,我会这样做的!谢谢你的帮助!我将遵循您的建议,使用Borodin的答案,因为我必须多次运行查询。谢谢您的帮助!我将遵循您的建议并使用Borodin的答案,因为我必须多次运行查询。