Perl 脚本:SQL 带有 IF 的命令显示为语法错误

Perl Script: SQL commands with IF are displayed as syntax errors

SQL 在 MySQL 数据库中运行的带有 IF 的命令显示为语法错误。

if (exists(
    SELECT * FROM tanss.leistungen
    where
    firmenid = Tanss
    and date(FROM_UNIXTIME(datum)) >= DATE_ADD(DATE_ADD(MAKEDATE(YEAR(CURRENT_DATE), 1), INTERVAL MONTH(CURRENT_DATE)-6 MONTH), INTERVAL -0 DAY)
    and date(FROM_UNIXTIME(datum)) < DATE_ADD(DATE_ADD(MAKEDATE(YEAR(CURRENT_DATE), 1), INTERVAL MONTH(CURRENT_DATE) MONTH), INTERVAL -0 DAY)
) =0 ,"ohne","vorhanden") as Leistung

或更简单如

if(niederlassung.name is null,"Niederlassung Warendorf",niederlassung.name) as Niederlassung

cmd 的错误输出是:

Bareword found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 123, near ") =0 ,"ohne" (Might be a runaway multi-line "" string starting on line 115) (Missing operator before ohne?) String found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 123, near "ohne","" Bareword found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 123, near "","vorhanden" (Missing operator before vorhanden?) String found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 123, near "left join tanss.anfahrtpauschale_preise as anfahrtfirma on anfahrtfirma.linkID = vertrag.id and anfahrtfirma.zoneID = "" (Missing semicolon on previous line?)

Bareword found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 115, near "if(niederlassung.name is null,"Niederlassung" (Might be a runaway multi-line "" string starting on line 111) (Do you need to predeclare if?)

我正在使用 DBD::ODBC

Perl 有什么方法可以接受这样的扩展 SQL 命令 而无需 我必须在脚本中编辑它,就像我目前所做的那样?

更新:

代码的主要部分(但仍不是完整代码):

    sub getLeadingMethode{
    $SQL = "
    SELECT
        vertrag.ID as VertragsDBid,
        vertrag.name as Vertragsart,
        vertrag.datumvon as von,
        vertrag.datumbis as bis,
        firmen.displayID as Tanss,
        firmen.name as Kundenname,
    if (exists(
            SELECT * FROM tanss.leistungen
            where
            firmenid = Tanss
            and date(FROM_UNIXTIME(datum)) >= DATE_ADD(DATE_ADD(MAKEDATE(YEAR(CURRENT_DATE), 1), INTERVAL MONTH(CURRENT_DATE)-6 MONTH), INTERVAL -0 DAY)
            and date(FROM_UNIXTIME(datum)) < DATE_ADD(DATE_ADD(MAKEDATE(YEAR(CURRENT_DATE), 1), INTERVAL MONTH(CURRENT_DATE) MONTH), INTERVAL -0 DAY)
        ) =0 ,"","") as Leistung

    FROM tanss.vertrag
        left join tanss.firmen on tanss.firmen.ID = vertrag.firmenID
        left join tanss.anfahrtpauschale_preise as anfahrtfirma on anfahrtfirma.linkID = vertrag.id and anfahrtfirma.zoneID = "" and anfahrtfirma.linktypid = ""
        left join (select * from tanss.firmen_fahrt as fahrt_1 where km_einfach =(select min(km_einfach) from tanss.firmen_fahrt where firmenID = fahrt_1.firmenid) ) as anfahrt on anfahrt.firmenID = firmen.id
        left join tanss.firmen as niederlassung on niederlassung.id = anfahrt.mandantID
        left join tanss.f_info_werte as vb on vb.firmenid = firmen.id and defID = "";";

完整错误信息:

C:\Entwicklung\LWEI_SampleCodes>sampleCode20.pl
Scalar found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 115, near ") =0 ,""
  (Might be a runaway multi-line "" string starting on line 100)
        (Missing operator before ?)
String found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 115, near "",""
        (Missing operator before ","?)
Scalar found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 115, near "",""
        (Missing operator before ?)
String found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 115, near "left join tanss.anfahrtpauschale_preise as anfahrtfirma on anfahrtfirma.linkID = vertrag.id and anfahrtfirma.zoneID = ""
        (Missing semicolon on previous line?)
Scalar found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 119, near "left join tanss.anfahrtpauschale_preise as anfahrtfirma on anfahrtfirma.linkID = vertrag.id and anfahrtfirma.zoneID = ""
  (Might be a runaway multi-line "" string starting on line 115)
        (Do you need to predeclare left?)
String found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 119, near "" and anfahrtfirma.linktypid = ""
        (Missing operator before " and anfahrtfirma.linktypid = "?)
Scalar found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 119, near "" and anfahrtfirma.linktypid = ""
        (Missing operator before ?)
String found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 119, near "left join tanss.f_info_werte as vb on vb.firmenid = firmen.id and defID = ""
        (Missing semicolon on previous line?)
Scalar found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 122, near "left join tanss.f_info_werte as vb on vb.firmenid = firmen.id and defID = ""
  (Might be a runaway multi-line "" string starting on line 119)
        (Do you need to predeclare left?)
String found where operator expected at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 122, near """
        (Missing semicolon on previous line?)
syntax error at C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl line 115, near ") =0 ,""
Execution of C:\Entwicklung\LWEI_SampleCodes\sampleCode20.pl aborted due to compilation errors.
    $SQL = "
    .......
        ) =0 ,"","") as Leistung

双引号字符串中有 un-escaped 个双引号。这会破坏你的报价。您需要转义引号,例如:

    $SQL = "
    .......
        ) =0 ,\"\",\"\") as Leistung

或使用qq/q...

    $SQL = qq#
    .......
        ) =0 ,"","") as Leistung
    #

或使用heredoc.....

    $SQL = <<"END_SQL"
    .......
        ) =0 ,"","") as Leistung
END_SQL

或者如果您正在使用 DBI, instead of interpolating variables in a string, you should use placeholders

    $SQL = "
    .......
        ) =0 , ? , ?) as Leistung

然后在您的执行语句中提供变量。

$dbi->prepare($SQL);        # sample code, not for use
$dbi->execute(, );

此外,变量 </code>、<code> 等是用于正则表达式匹配捕获的 built-in 变量。使用与正则表达式捕获如此分离的它们可能很危险。我假设你正在做类似的事情..

if ($foo =~ /(...)(...)..../) {   # capturing  ....  etc
    getLeadingMethode();          # relying on global scope variables

但最好将值与子调用一起传递,如下所示:

if ($foo =~ /(...)(...)..../) {     # capturing  ....  etc
    getLeadingMethode(, , );  # passing values directly, encapsulated approach

就像我上面说的,对于 DBI,您想使用占位符并让模块处理引用。