2012-12-20 38 views
8

मैं निम्नलिखित पुनश्च समारोह है:पावरहेल क्यों सोचता है कि मैं किसी ऑब्जेक्ट को वापस करने की कोशिश कर रहा हूं [] बल्कि डेटाटेबल?

function GetBuildData { 
    [System.Data.SqlClient.SqlConnection] $conn = New-Object System.Data.SqlClient.SqlConnection 
    [System.Data.SqlClient.SqlCommand] $cmd = New-Object System.Data.SqlClient.SqlCommand 
    [System.Data.SqlClient.SqlDataAdapter] $adapter = New-Object System.Data.SqlClient.SqlDataAdapter 
    [System.Data.DataTable] $dt = New-Object System.Data.DataTable 

    try { 
     [string] $connStr = "myConnectionString" 

     $conn.ConnectionString = $connStr 
     $cmd.Connection = $conn 
     $cmd.CommandText = "SELECT * FROM TestTable" 

     $conn.Open 

     $adapter.SelectCommand = $cmd 

     $adapter.Fill($dt) 

     $conn.Close 
    } 
    catch [system.exception] 
    { 
     Write-Host $_ 
    } 
    finally { 
     $adapter.Dispose 
     $cmd.Dispose 
     $conn.Dispose 
    } 

    return $dt 
} 

समारोह के अधिकांश संक्षिप्तता के लिए हटा दिया गया है। समस्या मेरे पास है तब होता है जब मैं बहुत तरह फ़ंक्शन को कॉल करें:

[System.Data.DataTable] $buildData = GetBuildData

मैं निम्नलिखित त्रुटि मिलती है:

Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Data.DataTable".

Powershell क्यों लगता है कि मैं एक वस्तु [] सरणी लौटे चाहने कर रहा हूँ है जब यह स्पष्ट है कि $ dt चर डेटाटेबल है?

संपादित करें:

मैं दोबारा जांच करती हैं, और $dt डेटा शामिल करता है। उदाहरण के लिए, पंक्तियों की संख्या। गणना 1 है जो अपेक्षित है।

+0

त्रुटि किस त्रुटि पर होती है? त्रुटि संदेश लाइन और चरित्र संख्या प्रदान करना चाहिए। मुझे लगता है कि यह यहां होता है: $ एडाप्टर। भरें ($ डीटी) ?? – D3vtr0n

+0

क्या आपने कभी भी ',' ऑपरेटर को jpmc26 के उत्तर में सुझाए गए प्रयासों का प्रयास किया था? मैं इस समस्या में भाग गया, और वह समाधान था। –

+0

क्या कोई उत्तर आपकी समस्या का समाधान करता है? यदि नहीं, तो क्या आप कुछ और जानकारी जोड़ सकते हैं कि उन्होंने क्यों काम नहीं किया? – jpmc26

उत्तर

13

मुझे अन्य मुद्दों के बारे में पता नहीं है, लेकिन मैं दो संभावित कारणों के बारे में सोच सकता हूं कि आप Object[] क्यों वापस प्राप्त कर रहे हैं।

  1. ऐसा हो सकता है कि आपने फ़ंक्शन में कहीं और आउटपुट आउटपुट नहीं किया हो। आपके मामले में, Fillint देता है। इसे अपने फ़ंक्शन कॉल के अंत में जोड़ने का प्रयास करें:

    | Out-Null 
    

    उदा।,

    $adapter.Fill($dt) | Out-Null 
    

    किसी भी बयान एक मान देता है और आप इसे कब्जा नहीं कर रहे हैं, उत्पादन अपनी वापसी मूल्य में शामिल किया जाएगा, और जब से तुम उस बिंदु पर कई वापसी मान होगा, PowerShell उन सब सामान होगा एक सरणी में

  2. दूसरी संभावना यह है कि पावरशेल सभी प्रकार के संग्रह को Object[] एस में परिवर्तित कर देता है। unmangled मान देने के लिए , ऑपरेटर का उपयोग करें:

    return , $dt 
    

    , केवल मूल्य इस प्रकार है कि युक्त एक सरणी पैदा करता है। जैसा कि मैं अनुमान लगा सकता हूं, यह PowerShell को बाहरीतम सरणी को स्वचालित रूप से अनलॉक करने का कारण बनता है और मान को अकेला छोड़ देता है, क्योंकि वास्तविक रिटर्न मान अब एक सरणी है जिसमें केवल एक मान होता है।

    return वास्तव में वैकल्पिक है, क्योंकि वापसी मूल्य में uncaptured मूल्य शामिल हैं।

    कल कल ही इस में भाग गया। मैं अपने जीवन के लिए यह नहीं समझ सकता कि क्यों कोई भी चुपचाप Object[] में कनवर्ट करना सोचता है।

+2

यही जवाब है! अब मैं दीवार को अपने सिर के कारण होने वाली क्षति से मरम्मत कर सकता हूं। "मैं अपने जीवन के लिए नहीं समझ सकता कि क्यों कोई भी चुपचाप 'ऑब्जेक्ट []' में परिवर्तित हो रहा है, उपयोगी है।" हो सकता है कि माइक्रोसॉफ्ट के पास दीवार मरम्मत ठेकेदार के साथ किकबैक सौदा हो? –

+0

बीटीडब्ल्यू, मुझे लगता है कि इसे ** वापसी ** के साथ जोड़ा जा सकता है, यानी 'वापसी, $ डीटी' भी काम करता है यदि आप ** $ dt ** unconverted वापस करना चाहते हैं और वहां फ़ंक्शन को समाप्त करना चाहते हैं। –

+0

एक और नोट जो मैं जोड़ना चाहता हूं वह यह है कि रूपांतरण तब होता है जब आप ** वापसी ** कीवर्ड का उपयोग नहीं करते हैं। यदि अंतिम अभिव्यक्ति का मूल्यांकन ** $ dt ** अकेला है, तो फ़ंक्शन ऑब्जेक्ट सरणी देता है। –

0

आपके द्वारा पोस्ट किए गए कुछ में आपके पास कुछ समस्याएं हैं। चूंकि आप स्पष्ट रूप से New-Object System.Data.DataTable के साथ डेटाटेबल ऑब्जेक्ट बनाते हैं, इसलिए डेटाटेबल प्रकार को [System.Data.DataTable] के साथ भी इसे सह करने का कोई कारण नहीं है। जब आप फ़ंक्शन को कॉल करते हैं तो वही सच है। आप डेटाटेबल ऑब्जेक्ट लौट रहे हैं, इसलिए आप वापस आ जाएंगे। इसके अलावा यदि आप चर प्रकार निर्दिष्ट करना चाहते हैं, तो प्रकार पहचानकर्ता और चर नाम के बीच कोई स्थान नहीं होना चाहिए। भले ही, ये मुद्दे उस व्यवहार का कारण नहीं बनेंगे जो आप देख रहे हैं। मैंने यह कोड चलाया:

function GetBuildData { 
    $dt = New-Object System.Data.DataTable 
    $column1 = New-Object system.Data.DataColumn 'Col1' 
    $column2 = New-Object system.Data.DataColumn 'Col2' 
    $dt.columns.add($column1) 
    $dt.columns.add($column2) 
    $row = $dt.NewRow() 
    $row.col1 = '1' 
    $row.col2 = '2' 
    $dt.rows.add($row) 

    return $dt 
} 

$buildData = GetBuildData 
$buildData 
Col1                  Col2 
----                  ---- 
1                  2 

और यह ठीक काम करता है। मुझे संदेह है कि आपकी समस्या का कारण बनने वाला थोड़ा सा संभवतः उस बिट में है जिसे आपने ब्रेवटी के लिए बाहर रखा है। शॉर्टकट शायद ही कभी हैं और आपको शायद ही कभी आंशिक डेटा से सटीक उत्तर मिलते हैं।

+0

मैंने पूरे फंक्शन को जोड़ा है, बस अगर कोई संकेत देता है कि यह मेरे लिए क्यों काम नहीं कर रहा है। –

+0

फ़ंक्शन में, यदि आपके पास $ dt की सामग्री आउटपुट है, तो क्या इसमें डेटा है? यदि आप फ़ंक्शन में $ dt.GetType() करते हैं, तो यह $ dt क्या लगता है? – EBGreen

+1

जब आप चर बनाते हैं तो मैं उन सभी प्रकार के पहचानकर्ताओं से छुटकारा पाने का भी सुझाव दूंगा। वे अनावश्यक हैं और समस्या पैदा कर सकते हैं हालांकि मुझे ऐसा नहीं लगता है। – EBGreen

0

एक योगदान कारक यह है कि आप वास्तव में खुली और करीबी विधियों को नहीं बुला रहे हैं, लेकिन इसके बजाय उनका जिक्र करते हैं। पावरशेल इन विधियों के साथ-साथ डेटाटेबल के संदर्भ को आउटपुट कर रहा है (जो मुझे लगता है कि वास्तव में इस तथ्य के कारण पॉप्युलेट नहीं किया गया है कि कनेक्शन खुला नहीं है)।

आप इस तरह खोलने/बंद करने के तरीकों पर कोष्ठक शामिल करने की जरूरत:

$conn.Open() 
... 
$conn.Close() 

तुम भी तरीकों जो लौट मूल्यों (.Add() पद्धतियों इस के लिए कुख्यात रहे हैं) के प्रति सतर्क रहने की जरूरत है कि आप ' एक चर या पाइपिंग को बाहर निकालने के लिए असाइन करके या तो उपभोग नहीं कर रहे हैं।

0

तुम सिर्फ अपने सभी डॉट आदेशों चर

function GetBuildData { 
    [System.Data.SqlClient.SqlConnection] $conn = New-Object System.Data.SqlClient.SqlConnection 
    [System.Data.SqlClient.SqlCommand] $cmd = New-Object System.Data.SqlClient.SqlCommand 
    [System.Data.SqlClient.SqlDataAdapter] $adapter = New-Object System.Data.SqlClient.SqlDataAdapter 
    [System.Data.DataTable] $dt = New-Object System.Data.DataTable 

    try { 
     [string] $connStr = "myConnectionString" 

     $conn.ConnectionString = $connStr 
     $cmd.Connection = $conn 
     $cmd.CommandText = "SELECT * FROM TestTable" 

     [void]$conn.Open 

     $adapter.SelectCommand = $cmd 

     $adapter.Fill($dt) 

     [void]$conn.Close 
    } 
    catch [system.exception] 
    { 
     Write-Host $_ 
    } 
    finally { 
     [void]$adapter.Dispose 
     [void]$cmd.Dispose 
     [void]$conn.Dispose 
    } 

    $dt 
} 

अपने प्रश्न क्यों के रूप में करने के लिए आवंटित नहीं कर रहे हैं बाहर शून्य करने के लिए है? ... पढ़ें किथ हिल का ब्लॉग: how does return work powershell functions