2013-05-24 8 views
5

पर्ल और डीबीआई का उपयोग करके PostgreSQL में एक मान सेट करने की कोशिश कर रहा है, और इस प्रकार डीबीडी :: पीजी।

मुझे एक अजीब त्रुटि मिल रही है।

2013-05-23 19:02:36.641139500 updating status to 0 
2013-05-23 19:02:36.641410500 DBD::Pg::st execute failed: ERROR: syntax error at or near "$1" 
2013-05-23 19:02:36.641418500 LINE 1: UPDATE instances SET $1 = $2 
2013-05-23 19:02:36.641423500       ^at /usr/lib/perl5/vendor_perl/Mitel/MslRest/mbg.pm line 161. 
2013-05-23 19:02:36.642425500 [Thu May 23 19:02:36 2013] [error] DBD::Pg::st execute failed: ERROR: syntax error at or near "$1" 
2013-05-23 19:02:36.642438500 LINE 1: UPDATE instances SET $1 = $2 
2013-05-23 19:02:36.642443500       ^at /usr/lib/perl5/vendor_perl/Mitel/MslRest/mbg.pm line 161. 
2013-05-23 19:02:36.642447500 

प्रासंगिक कोड

my $sql = "UPDATE instances SET ? = ?"; 
my $dbh = Mitel::tug::getdbh(); 
$dbh->begin_work; 
my $sth = $dbh->prepare($sql); 
unless ($sth) { 
    return $self->internal_error("prepare failed: " . $dbh->errstr); 
} 
foreach my $propname (sort keys %{ $raw_data }) { 
    my $propval = $raw_data->{$propname}; 
    print STDERR "updating $propname to $propval\n"; 
    if (! $sth->execute($propname, $propval)) { 
     $dbh->rollback; 
     $sth->finish; 
     return $self->internal_error("execute: " . $dbh->errstr); 
    } 
} 
$dbh->commit; 
$sth->finish; 

तो मैं निष्पादित विधि का उपयोग एसक्यूएल इंजेक्शन को रोकने के लिए 0 करने के लिए "स्थिति" अद्यतन करने के लिए कोशिश कर रहा हूँ, लेकिन मैं कुछ के लिए सिंटैक्स त्रुटि हो रही है है कारण।

कोई भी इसमें भाग लेता है?

[email protected] ~]# perl -v 

This is perl, v5.10.1 (*) built for i386-linux-thread-multi 

perl-DBD-Pg-2.15.1-4.el6_3.i686 
postgresql84-server-8.4.14-1PGDG.rhel6.i686 

[email protected] ~]# uname -a 
Linux miketug2 2.6.32-279.22.1.el6.i686 #1 SMP Wed Feb 6 00:31:03 UTC 2013 i686 i686 i386 GNU/Linux 

उत्तर

9

PostgreSQL पसंद है कि आप स्थितीय ? प्लेसहोल्डर तो किसी प्लेसहोल्डर नंबर पर अपने ? प्लेसहोल्डर का अनुवाद है पर गिने प्लेसहोल्डर ($1, $2, ...) का उपयोग करें;

UPDATE instances SET $1 = $2 
त्रुटि संदेश में

:

UPDATE instances SET ? = ? 

के रूप में समाप्त होता है: यही कारण है कि अपने एसक्यूएल है।

अब वास्तविक समस्या यह है कि आप पहचानकर्ताओं (तालिका नाम, कॉलम नाम, ...) के लिए प्लेसहोल्डर्स का उपयोग नहीं कर सकते हैं, आप केवल मूल्यधारकों को मूल्यों के लिए उपयोग कर सकते हैं। आप SET ? = ? नहीं कह सकते हैं, आपको शायद स्ट्रिंग इंटरपोलेशन के माध्यम से कॉलम नाम को किसी अन्य तरीके से आपूर्ति करना होगा। इसका मतलब है आप कुछ इस तरह करने के लिए अपने पाश के अंदर अपने prepare स्थानांतरित करने के लिए है:

foreach my $propname (sort keys %{ $raw_data }) { 
    my $prop = $dbh->quote_identifier($propname); 
    my $propval = $raw_data->{$propname}; 
    my $sth  = $dbh->prepare("UPDATE instances SET $prop = ?"); 
    $sth->execute($propval); 
    $sth->finish(); 
} 

आपका वास्तविक कोड होगा, ज़ाहिर है, त्रुटि हैंडलिंग शामिल हैं। कॉलम नाम इंटरपोलेशन के लिए सुरक्षित बनाने के लिए quote_identifier के उपयोग पर ध्यान दें। यदि आप इस सरल prepare, execute, finish अनुक्रम के साथ समाप्त होने जा रहे हैं तो आप इसके बजाय do का उपयोग करना चाहेंगे।

+0

हां, यह समस्या हल करता है। धन्यवाद! –

+0

+1 के लिए +1: _ आप पहचानकर्ताओं के लिए प्लेसहोल्डर का उपयोग नहीं कर सकते (तालिका के नाम, कॉलम नाम, ...) _ ... धन्यवाद! –

संबंधित मुद्दे