2010-05-18 5 views
5

मेरे पास एक पाइप सीमांकित टेक्स्ट फ़ाइल के अनुसार पोस्टग्रेस में डेटा डालने वाला एक पर्ल स्क्रिप्ट है। कभी-कभी, एक फ़ील्ड शून्य (अपेक्षित के रूप में) है। हालांकि, पर्ल इस क्षेत्र को एक खाली स्ट्रिंग में बनाता है और पोस्टग्रेस सम्मिलन कथन विफल रहता है।मैं पर्ल के डीबीडी :: पीजी के साथ शून्य फ़ील्ड कैसे डालूं?

यहाँ कोड का एक टुकड़ा है:


use DBI; 

#Connect to the database. 
$dbh=DBI->connect('dbi:Pg:dbname=mydb','mydb','mydb',{AutoCommit=>1,RaiseError=>1,PrintError=>1}); 

#Prepare an insert. 
$sth=$dbh->prepare("INSERT INTO mytable (field0,field1) SELECT ?,?"); 

while (<>){ 
    #Remove the whitespace 
    chomp; 

    #Parse the fields. 
    @field=split(/\|/,$_); 

    print "$_\n"; 

    #Do the insert. 
    $sth->execute($field[0],$field[1]); 
} 

और अगर इनपुट है:

 
a|1 
b| 
c|3 

संपादित करें: इस इनपुट के बजाय का उपयोग करें।

 
a|1|x 
b||x 
c|3|x 

यह b| पर विफल हो जाएगा।

DBD::Pg::st execute failed: ERROR: invalid input syntax for integer: ""

मैं बस इसके बजाय field1 पर एक शून्य डालना चाहता हूं। कोई विचार?

संपादित करें: मैंने अंतिम मिनट में इनपुट को सरल बना दिया। पुराने इनपुट ने वास्तव में इसे किसी कारण से काम किया है। तो अब मैंने इनपुट को कुछ ऐसा बदल दिया जो प्रोग्राम को विफल कर देगा। यह भी ध्यान रखें कि फ़ील्ड 1 एक निरर्थक पूर्णांक डेटाटाइप है।

+0

इस कोड को यहाँ काम करता है, पर्ल 5.10.1, DBD :: Pg 2.15.1 यूएनडीईएफ को , पोस्टग्रेर्स 8.4। आप SELECT का उपयोग क्यों कर रहे हैं? VALUES के बजाय (?,?)? – MkV

+0

इसके अलावा, सख्त उपयोग करें; चेतावनियों का प्रयोग करें; और अपनी परिवर्तनीय घोषणाओं को ठीक करें – MkV

+0

एसक्यूएल प्रारूप के बारे में .. असली कोड वास्तव में कुछ उस चयन पर शामिल हो गया है। – User1

उत्तर

4

मुझे यकीन है कि आप कि क्या आपके चिपकाया कोड और डेटा एक साथ परीक्षण नहीं कर रहा हूँ, वे पर्ल 5.10.1, DBD :: Pg 2.15.1 और Postgres 8.4 के साथ काम करते हैं। इसके अलावा आपको सख्त और चेतावनियों का उपयोग करना चाहिए और अपने चर के लिए पैकेज स्कोप पर भरोसा नहीं करना चाहिए।

यदि आप तीन या अधिक फ़ील्ड का उपयोग करने के लिए अपना कोड और डेटा बदलते हैं, तो गैर-टर्मिनल एक खाली छोड़कर, आप डीबीडी :: पीजी से त्रुटि को ट्रिगर कर सकते हैं। तैयार बयान को क्रियान्वित करने से पहले अपने कोड के लिए इस तरह की एक पंक्ति जोड़ दें:

map { $_ eq '' and $_ = undef } @field; 

@field में रिक्त स्ट्रिंग नक़्शा बनाने के लिए

+0

उसने खाली तारों को नल में परिवर्तित करने का ख्याल रखा। यह अजीब बात है कि इनपुट में किसी फ़ील्ड को हटाने से खाली स्ट्रिंग शून्य हो जाती है (कम से कम ऐसा लगता है कि ऐसा हुआ है)। – User1

+0

फ़ोरैच –

+0

पर अधिक पढ़ा जा सकता है यदि कोई स्ट्रिंग उन वर्णों में समाप्त होती है जिन्हें आप विभाजित कर रहे हैं, जैसे 'a | 4 |' तो अंतिम सरणी तत्व बिल्कुल भर नहीं जाता है, एक खाली स्ट्रिंग में नहीं बदला जाता है, इसलिए यह अनिश्चित है, perldoc -f विभाजन देखें। – MkV

0

undef आमतौर पर नल के लिए नक्शे। ऐसा लगता है कि आप खाली स्ट्रिंग डालने वाले हैं जो undef जैसा नहीं है।

+0

आपने कोड का परीक्षण किया? केवल दो क्षेत्रों के साथ? – MkV

2

डीबीआई पैकेज मानचित्र undef से NULL पर नक्शा। (पर्ल के परिभाषित सत्ता बनाम झूठ तर्क वास्तव में एसक्यूएल के trinary तर्क के लिए एक बहुत अच्छी फिट है।)

तो, अपने while पाश में, बस अगर संकेत क्षेत्र में रिक्त स्ट्रिंग है की जाँच करें, और यदि हां, तो यह undef बनाने बजाय:

while (<>){ 
    ... 
    #Parse the fields. 
    @field=split(/\|/,$_); 

    if ($field[1] eq '') { 
     # handle NULLs 
     $field[1] = undef; 
    } 

    #Do the insert. 
    $sth->execute($field[0],$field[1]); 
} 
+0

आपका यदि कभी सच नहीं है, और यदि आप सख्त उपयोग करते हैं; चेतावनियों का प्रयोग करें; आपके कोड पर आपको स्ट्रिंग eq ' – MkV

+1

@james में अनियमित मूल्य $ फ़ील्ड [1] का उपयोग मिलता है, मुझे यकीन नहीं है कि आपका क्या मतलब है। यह 'सख्त' और 'चेतावनियों' सक्षम और सशर्त सफलताओं के साथ ठीक काम करता है।'perl -mstrict -Mwarnings -MData :: Dumper -le 'my $ str =" a | b || d "; मेरा @ ए = विभाजन/\ | /, $ str; अगर ($ एक [2] eq "") {$ a [2] = undef; }; प्रिंट डम्पर \ @ ए'' – friedo

+0

यह अब काम करता है, लेकिन जैसा कि मूल रूप से सवाल उठाया गया था (और जैसा कि आपने इसका उत्तर दिया था), केवल 2 फ़ील्ड थे और खाली क्षेत्र अंत में था, उस सूचकांक के लिए अपरिचित लौट रहा था। – MkV

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