PowerShell से SQL सर्वर क्वेरी कैसे चलाते हैं?


161

क्या मेरे स्थानीय मशीन पर Powershell का उपयोग करते हुए SQL सर्वर पर एक मनमाना क्वेरी निष्पादित करने का एक तरीका है?

जवाबों:


166

दूसरों के लिए, जिन्हें केवल स्टॉक .net और PowerShell (कोई अतिरिक्त SQL उपकरण स्थापित नहीं) के साथ ऐसा करने की आवश्यकता है, यहां वह फ़ंक्शन है जो मैं उपयोग करता हूं:

function Invoke-SQL {
    param(
        [string] $dataSource = ".\SQLEXPRESS",
        [string] $database = "MasterData",
        [string] $sqlCommand = $(throw "Please specify a query.")
      )

    $connectionString = "Data Source=$dataSource; " +
            "Integrated Security=SSPI; " +
            "Initial Catalog=$database"

    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
    $connection.Open()

    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataSet) | Out-Null

    $connection.Close()
    $dataSet.Tables

}

मैं इसे बहुत लंबे समय से इस्तेमाल कर रहा हूं, मुझे नहीं पता कि किसने कौन से हिस्से लिखे लेकिन यह दूसरे के उदाहरणों से डिस्टिल्ड था लेकिन स्पष्ट होने के लिए सरलीकृत किया गया था और अतिरिक्त निर्भरता या सुविधाओं के बिना बस जरूरत है।

मैं इसे अक्सर उपयोग करता हूं और साझा करता हूं कि मैंने इसे GitHub पर एक स्क्रिप्ट मॉड्यूल में बदल दिया है ताकि आप अब अपने मॉड्यूल निर्देशिका पर जा सकें और निष्पादित कर सकें git clone https://github.com/ChrisMagnuson/InvokeSQLऔर उस बिंदु से आगे इनवॉइस-लोड हो जाएगा जब आप इसका उपयोग करने के लिए जाएंगे (अनुमान लगाते हुए आपके शक्तियां v3 या बाद के संस्करण का उपयोग करते हुए)।


क्या निपटान यहाँ या शक्तियों में मायने नहीं रखता है?
मास्लो

2
@Maslow मैं निश्चित रूप से नहीं कह सकता, मुझे पता है कि यह वस्तुओं के निपटान के बिना ठीक काम करता है, लेकिन अगर आपके पास एक एकल powerhell.exe प्रक्रिया है, जो बंद किए बिना हफ्तों में कई बार कॉल करेगी तो यह अंततः एक मुद्दा हो सकता है लेकिन आप कि परीक्षण करना होगा।
क्रिस मैग्नसन

1
ध्यान दें कि यह आपको स्क्रिप्ट लिखने के लिए मजबूर करता है जो sql इंजेक्शन हमलों के लिए असुरक्षित हो सकता है, यदि वे उस स्रोत के क्वेरी के डेटा को पढ़ने पर निर्भर करते हैं जो उपयोगकर्ता इनपुट पर निर्भर करता है।
जोएल कोएहॉर्न

4
@AllTradesJack Google Sql Injection। Invoke-Sql कमांड में कमांड टेक्स्ट से अलग पैरामीटर को शामिल करने का कोई तरीका नहीं है। यह बहुत अधिक गारंटी देता है कि आपने प्रश्नों का निर्माण करने के लिए स्ट्रिंग संयोजन का उपयोग किया है, और यह एक बड़ा नहीं-नहीं है।
जोएल कोएहॉर्न

1
मेरे लिए अच्छा काम करता है। किसी को $connection.dispose()
आश्चर्यचकित

101

आप Invoke-Sqlcmdcmdlet का उपयोग कर सकते हैं

Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"

http://technet.microsoft.com/en-us/library/cc281720.aspx


22
किसी को यह उल्लेख करना चाहिए कि यदि आप sql सर्वर के संदर्भ में हैं, तो यह बहुत अच्छा हो सकता है, लेकिन यदि आप अपने वर्कस्टेशन का उपयोग कर रहे हैं तो ऐसा नहीं है ...
aikeru

10
आप इसे कहीं भी चला सकते हैं SQL सर्वर क्लाइंट उपकरण (SSMS) स्थापित हैं। यह किसी भी कार्य केंद्र से ठीक काम करता है, चाहे वह SQL सर्वर चल रहा हो या नहीं।
17

3
Cmdlet उपलब्ध होने के लिए निम्नलिखित आयात का उपयोग करें: Import-Module "sqlps" -DisableNameChecking
xx1xx

1
यदि आप अभी भी SQL 2008 R2 पर हैं, तो आपको मॉड्यूल के आसपास किसी काम का उपयोग करने की आवश्यकता है: sev17.com/2010/07/10/making-a-sqlps-module
विंसेंट डी स्मेट

2
आह्वान-SqlCmd विचित्र किनारे के मामलों और असंगत व्यवहार का एक अंतहीन दुःस्वप्न है। यह कभी-कभी स्तंभों को आउटपुट क्यों करता है और अन्य बार क्यों नहीं? मेरे त्रुटि संदेश कहां हैं? यह एक कंप्यूटर पर क्यों है या दूसरे में नहीं है? इसे कैसे स्थापित किया जा सकता है? प्रत्येक प्रश्न का उत्तर पिछले से भी बदतर है।
21

28

यहाँ एक उदाहरण मुझे इस ब्लॉग पर मिला है ।

$cn2 = new-object system.data.SqlClient.SQLConnection("Data Source=machine1;Integrated Security=SSPI;Initial Catalog=master");
$cmd = new-object system.data.sqlclient.sqlcommand("dbcc freeproccache", $cn2);
$cn2.Open();
if ($cmd.ExecuteNonQuery() -ne -1)
{
    echo "Failed";
}
$cn2.Close();

संभवतः आप एक अलग TSQL बयान स्थानापन्न कर सकते हैं जहाँ यह कहता है dbcc freeproccache


1
इस समाधान ने मेरे लिए काम किया, हालांकि, ExecuteNonQuery()सफलता पर शून्य वापस आ गया, जिस स्थिति का मैं उपयोग करता हूं वह है if ($cmd.ExecuteNonQuery() -ne 0):।
गिक्सबेल

लगता है यह प्रभावित लाइनों की संख्या लौटाता है। docs.microsoft.com/en-us/dotnet/api/…
निकोलस

27

यह फ़ंक्शन पॉवरशेल ऑब्जेक्ट्स की एक सरणी के रूप में एक क्वेरी के परिणाम लौटाएगा ताकि आप उन्हें फ़िल्टर में उपयोग कर सकें और कॉलम आसानी से एक्सेस कर सकें:

function sql($sqlText, $database = "master", $server = ".")
{
    $connection = new-object System.Data.SqlClient.SQLConnection("Data Source=$server;Integrated Security=SSPI;Initial Catalog=$database");
    $cmd = new-object System.Data.SqlClient.SqlCommand($sqlText, $connection);

    $connection.Open();
    $reader = $cmd.ExecuteReader()

    $results = @()
    while ($reader.Read())
    {
        $row = @{}
        for ($i = 0; $i -lt $reader.FieldCount; $i++)
        {
            $row[$reader.GetName($i)] = $reader.GetValue($i)
        }
        $results += new-object psobject -property $row            
    }
    $connection.Close();

    $results
}

ए भरने पर यह बेहतर क्यों है DataTable( एडम का जवाब देखें )।
alroc

2
शायद बहुत बड़ा अंतर नहीं है, लेकिन SqlDataReaders को आमतौर पर पसंद किया जाता है क्योंकि वे कम संसाधनों का उपभोग करते हैं। यहाँ प्रासंगिक होने की संभावना नहीं है, लेकिन डेटाटेबल के बजाय वास्तविक वस्तुओं को वापस प्राप्त करना अच्छा है जिसे आप फ़ॉर्च में उपयोग कर सकते हैं और जहां डेटा के स्रोत के बारे में चिंता किए बिना क्लॉज़ होता है।
mcobrien

1
एक उदाहरण का उपयोग अच्छा होगा।
एरिक श्नाइडर

कभी-कभी पर्याप्त तारे नहीं होते हैं
फ्रेड बी

13

यदि आप इसे SQL सर्वर के संदर्भ में अपने स्थानीय मशीन पर करना चाहते हैं तो मैं निम्नलिखित का उपयोग करूंगा। यह वही है जो हम अपनी कंपनी में उपयोग करते हैं।

$ServerName = "_ServerName_"
$DatabaseName = "_DatabaseName_"
$Query = "SELECT * FROM Table WHERE Column = ''"

#Timeout parameters
$QueryTimeout = 120
$ConnectionTimeout = 30

#Action of connecting to the Database and executing the query and returning results if there were any.
$conn=New-Object System.Data.SqlClient.SQLConnection
$ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerName,$DatabaseName,$ConnectionTimeout
$conn.ConnectionString=$ConnectionString
$conn.Open()
$cmd=New-Object system.Data.SqlClient.SqlCommand($Query,$conn)
$cmd.CommandTimeout=$QueryTimeout
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[void]$da.fill($ds)
$conn.Close()
$ds.Tables

बस $ ServerName , $ डेटाबेसनाम और $ क्वेरी चर भरें और आपको जाने के लिए अच्छा होना चाहिए।

मुझे यकीन नहीं है कि हमें मूल रूप से यह कैसे पता चला, लेकिन यहां बहुत कुछ समान है



11

SQL क्वेरी चलाने का कोई अंतर्निहित "PowerShell" तरीका नहीं है। यदि आपके पास SQL सर्वर उपकरण स्थापित हैं , तो आपको एक Invoke-SqlCmd मिलेगा cmdlet ।

क्योंकि PowerShell .NET पर बनाया गया है, इसलिए आप अपने प्रश्नों को चलाने के लिए ADO.NET API का उपयोग कर सकते हैं ।


0

वर्कशॉप मापदंडों के साथ SQL इंजेक्शन से बचने के लिए आप इसका उपयोग कर सकते हैं


function sqlExecuteRead($connectionString, $sqlCommand, $pars) {

        $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
        $connection.Open()
        $command = new-object system.data.sqlclient.sqlcommand($sqlCommand, $connection)

        if ($pars -and $pars.Keys) {
            foreach($key in $pars.keys) {
                # avoid injection in varchar parameters
                $par = $command.Parameters.Add("@$key", [system.data.SqlDbType]::VarChar, 512);
                $par.Value = $pars[$key];
            }
        }

        $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
        $dataset = New-Object System.Data.DataSet
        $adapter.Fill($dataset) | Out-Null
        $connection.Close()
        return $dataset.tables[0].rows

    }

    $connectionString = "..."
    $sql = "select top 10 Message, TimeStamp, Level from dbo.log "+
        "where Message = @MSG and Level like @LEVEL ";
    $pars = @{
        MSG = 'this is a test from powershell'; 
        LEVEL = 'aaa%';
    };
    sqlExecuteRead $connectionString $sql $pars
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.