কিভাবে সি। এস। এসকিউএল স্ক্রিপ্ট ফাইল ব্যবহার করবেন


140

আমি নিশ্চিত যে এই প্রশ্নের উত্তর ইতিমধ্যে দেওয়া হয়েছে, তবে আমি অনুসন্ধান সরঞ্জামটি ব্যবহার করে কোনও উত্তর খুঁজে পেতে পারিনি।

সি # ব্যবহার করে আমি একটি .sql ফাইল চালাতে চাই। এসকিএল ফাইলটিতে একাধিক এসকিএল স্টেটমেন্ট রয়েছে, যার কয়েকটি একাধিক লাইনের উপর ভেঙে গেছে। আমি ফাইলটিতে পড়ার চেষ্টা করেছি এবং ODP.NET ব্যবহার করে ফাইলটি সম্পাদন করার চেষ্টা করেছি ... তবে আমি মনে করি না এক্সিকিউটননকুইয়ারি সত্যিই এটি করার জন্য ডিজাইন করা হয়েছে।

সুতরাং আমি একটি প্রক্রিয়া তৈরির মাধ্যমে স্ক্যালপ্লাস ব্যবহার করার চেষ্টা করেছি ... তবে আমি যদি সত্যিকার স্ক্যালপ্লাসে সেট ইউজশেলএক্সিকিউটের সাহায্যে প্রক্রিয়াটি তৈরি না করি তবে কখনই প্রস্থান করতে পারত না। এই কোডটি এখানে কাজ করে না।

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "sqlplus";
p.StartInfo.Arguments = string.Format("xx/xx@{0} @{1}", in_database, s);
p.StartInfo.CreateNoWindow = true;

bool started = p.Start();
p.WaitForExit();

ওয়েটফরএক্সিট কখনই ফিরে আসে না .... যদি না আমি UseShellExecute টি সত্যে সেট না করি। UseShellExecute এর একটি পার্শ্ব প্রতিক্রিয়া হ'ল আপনি কোনও পুনঃনির্দেশিত আউটপুট ক্যাপচার করতে পারবেন না।


8
হ্যালো মিঃ রিচ, আপনার প্রশ্নটি ওরাকল সম্পর্কে ছিল এবং আপনি এমন কোনও সমাধান গ্রহণ করেছিলেন যা স্কেল সার্ভারের জন্য ছিল? আপনি আপনার ডিবি স্কেল সার্ভারে পরিবর্তন করেছেন?
অক্ষয় জে

উত্তর:


185
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using System.IO;
using System.Data.SqlClient;

public partial class ExcuteScript : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    string sqlConnectionString = @"Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=ccwebgrity;Data Source=SURAJIT\SQLEXPRESS";

    string script = File.ReadAllText(@"E:\Project Docs\MX462-PD\MX756_ModMappings1.sql");

    SqlConnection conn = new SqlConnection(sqlConnectionString);

    Server server = new Server(new ServerConnection(conn));

    server.ConnectionContext.ExecuteNonQuery(script);
    }
}

4
গ্রেট! এই সমাধানটি আমার জন্য একটি ডেটাবেস ফেলে এবং পুনরায় তৈরি করতে এবং টেবিলগুলি যুক্ত করতে (রেফারেন্সড এসকিউএল স্ক্রিপ্ট ফাইলের মাধ্যমে) সক্ষম হয়ে কাজ করেছে।
ওগ্রে গীতসংহিতা 33

11
এই পদ্ধতিটি আপনার স্ক্রিপ্টে "GO" কমান্ড ব্যবহারের অনুমতি দেয় না যা আপনি এসকিউএল ম্যানেজমেন্ট স্টুডিও বা osql কমান্ড থেকে কোনও স্ক্রিপ্ট চালানোর সময় অনুমোদিত। msdn.microsoft.com/en-us/library/ms188037.aspx
Rn222

20
আরএন 222: আমি মনে করি আপনি এক্সিকিউটিভনকিউয়ের পদ্ধতিগুলি বিভ্রান্ত করেছেন, স্কেলকম্যান্ড.এক্সেকিউটনকনকোয়ারি "জিও" কমান্ডগুলি ব্যবহারের অনুমতি দেবে না, তবে সার্ভার.কনেকশনকন্টেক্সটেক্সটেক্সটনিউনকুয়ারি অবশ্যই (এটি আমি এখনই ব্যবহার করছি)।
পিটারবেলম

44
নোট করুন যে এই প্রকল্পটির উত্তরগুলির জন্য আপনাকে Microsoft.SqlServer.ConnicationInfo, Microsoft.SqlServer.Mageagement.Sdk এবং Microsoft.SqlServer.Smo- র প্রকল্পে রেফারেন্স যুক্ত করতে হবে।
থোমাসব

8
আমার কাছে এটা কাজ করে নি যখন .net 4.0 / 4.5 ব্যবহার করে, যখন উল্লেখ 110 \ SDK এর \ অ্যাসেম্বলিজ সমাধান আমি app.Config পরিবর্তন পেলেন<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/> </startup>
আবীর

107

আমি এই সমাধানটি মাইক্রোসফ্ট.এসএইচএল সার্ভার.ম্যানেজমেন্টের সাথে চেষ্টা করেছিলাম কিন্তু এটি নেট নেট 4.0.০ এর সাথে ভালভাবে কাজ করে নি তাই আমি কেবল নেট নেট লিবার ফ্রেমওয়ার্ক ব্যবহার করে অন্য একটি সমাধান লিখেছি।

string script = File.ReadAllText(@"E:\someSqlScript.sql");

// split script on GO command
IEnumerable<string> commandStrings = Regex.Split(script, @"^\s*GO\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase);

Connection.Open();
foreach (string commandString in commandStrings)
{
    if (!string.IsNullOrWhiteSpace(commandString.Trim()))
    {
        using(var command = new SqlCommand(commandString, Connection))
        {
            command.ExecuteNonQuery();
        }
    }
}     
Connection.Close();

যথাযথভাবে। এই সমাধানটি ফাইলটি এটি ব্যবহার করার পরেও বন্ধ করবে না। এটা সমালোচনা হতে পারে।
ম্যাথিয়াস লাইককেগার্ড লরেনজেন

1
"Go" বা "যান" কেসের ক্ষেত্রেও ম্যাচ করতে "RegexOptions.M Multilineline | RegexOptions.IgnoreCase" ব্যবহার করুন।
অঙ্কুশ

1
আমি মনে করি রিজেক্সঅপশনস.ক্ল্যাচারআইভারেন্টের পতাকাটিও ব্যবহার করা উচিত।
ডেভ অ্যান্ডারসন

3
এটি 100% কাজ করছে না: 'GO' সংখ্যার পরামিতি গ্রহণ করতে পারে।
nothrow

16

এটি ফ্রেমওয়ার্ক ৪.০ বা উচ্চতর ক্ষেত্রে কাজ করে। "Go" সমর্থন করে। ত্রুটি বার্তা, লাইন এবং sql কমান্ডটিও প্রদর্শন করুন।

using System.Data.SqlClient;

        private bool runSqlScriptFile(string pathStoreProceduresFile, string connectionString)
    {
        try
        {
            string script = File.ReadAllText(pathStoreProceduresFile);

            // split script on GO command
            System.Collections.Generic.IEnumerable<string> commandStrings = Regex.Split(script, @"^\s*GO\s*$",
                                     RegexOptions.Multiline | RegexOptions.IgnoreCase);
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                foreach (string commandString in commandStrings)
                {
                    if (commandString.Trim() != "")
                    {
                        using (var command = new SqlCommand(commandString, connection))
                        {
                        try
                        {
                            command.ExecuteNonQuery();
                        }
                        catch (SqlException ex)
                        {
                            string spError = commandString.Length > 100 ? commandString.Substring(0, 100) + " ...\n..." : commandString;
                            MessageBox.Show(string.Format("Please check the SqlServer script.\nFile: {0} \nLine: {1} \nError: {2} \nSQL Command: \n{3}", pathStoreProceduresFile, ex.LineNumber, ex.Message, spError), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return false;
                        }
                    }
                    }
                }
                connection.Close();
            }
        return true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return false;
        }
    }

3
নিস কোড, এক খুব ছোটখাট জিনিস যে প্রয়োজন নেই connection.Close()সংযোগ দ্বারা বন্ধ হয়ে যাবে usingআপনি এটি আপনার মধ্যে আবৃত করেছি।
বন্ধুত্বপূর্ণ

মহান কাজ. এটি আমার জন্য 'সরাসরি বাক্সের বাইরে' কাজ করেছিল।
স্টিফেন 85

8

স্কেল স্ক্রিপ্টটি ব্যাচ ফাইলে কার্যকর করতে কমান্ডটি লিখুন তারপরে নীচের কোডটি চালান

string batchFileName = @"c:\batosql.bat";
string sqlFileName = @"c:\MySqlScripts.sql";
Process proc = new Process();
proc.StartInfo.FileName = batchFileName;
proc.StartInfo.Arguments = sqlFileName;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.ErrorDialog = false;
proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(batchFileName);
proc.Start();
proc.WaitForExit();
if ( proc.ExitCode!= 0 )

ব্যাচ ফাইলে এই জাতীয় কিছু লিখুন (এসকিউএল সার্ভারের নমুনা)

osql -E -i %1

6

এটি আমার পক্ষে কাজ করে:

public void updatedatabase()
{

    SqlConnection conn = new SqlConnection("Data Source=" + txtserver.Text.Trim() + ";Initial Catalog=" + txtdatabase.Text.Trim() + ";User ID=" + txtuserid.Text.Trim() + ";Password=" + txtpwd.Text.Trim() + "");
    try
    {

        conn.Open();

        string script = File.ReadAllText(Server.MapPath("~/Script/DatingDemo.sql"));

        // split script on GO command
        IEnumerable<string> commandStrings = Regex.Split(script, @"^\s*GO\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase);
        foreach (string commandString in commandStrings)
        {
            if (commandString.Trim() != "")
            {
                new SqlCommand(commandString, conn).ExecuteNonQuery();
            }
        }
        lblmsg.Text = "Database updated successfully.";

    }
    catch (SqlException er)
    {
        lblmsg.Text = er.Message;
        lblmsg.ForeColor = Color.Red;
    }
    finally
    {
        conn.Close();
    }
}

4

সুরজিটের উত্তরে অতিরিক্ত উন্নতি যুক্ত করা হয়েছে:

using System;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using System.IO;
using System.Data.SqlClient;

namespace MyNamespace
{
    public partial class RunSqlScript : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var connectionString = @"your-connection-string";
            var pathToScriptFile = Server.MapPath("~/sql-scripts/") + "sql-script.sql";
            var sqlScript = File.ReadAllText(pathToScriptFile);

            using (var connection = new SqlConnection(connectionString))
            {
                var server = new Server(new ServerConnection(connection));
                server.ConnectionContext.ExecuteNonQuery(sqlScript);
            }
        }
    }
}

এছাড়াও, আমার প্রকল্পে আমাকে নিম্নলিখিত উল্লেখগুলি যুক্ত করতে হয়েছিল:

  • C:\Program Files\Microsoft SQL Server\120\SDK\Assemblies\Microsoft.SqlServer.ConnectionInfo.dll
  • C:\Program Files\Microsoft SQL Server\120\SDK\Assemblies\Microsoft.SqlServer.Smo.dll

সেগুলিতে সি: \ প্রোগ্রাম ফাইলস \ মাইক্রোসফ্ট এসকিউএল সার্ভারের বেশ কয়েকটি ফোল্ডার রয়েছে তবে আমার প্রয়োগে এই দুটি কাজ করার জন্য সেগুলি সঠিক ডেল: এস ব্যবহার করার জন্য আমার কোনও ধারণা নেই।


এটি নেট। 4.7 এ আমার জন্য কাজ করেছে। সুরজিৎ দ্বারা উল্লিখিত অন্যান্য ঘরগুলির আমার দরকার নেই। যাইহোক, সার্ভার সংযোগটি ইনস্ট্যান্ট করার সময় 13.100.0.0 হিসাবে আমার মাইক্রোসফ্ট.এসএইচএল সার্ভার.কনেকশনআইএনফো এবং মাইক্রোসফ্ট.এসএলএস সার্ভার.স্মো উভয়ের জন্য 13.0.0.0 সংস্করণটি ব্যবহার করতে হয়েছিল।
কেভিন ফিচার

4

আমি ম্যানুয়ালটি পড়ে উত্তরটি কার্যকর করতে পেরেছি :)

এমএসডিএন থেকে এই নিষ্কাশন

কোড উদাহরণটি পি.স্ট্যান্ডার্ডআউটপুটকে কল করে একটি অচলাবস্থার পরিস্থিতি এড়ায় p যদি পিতামহী প্রসেস পি। স্ট্যান্ডার্ডআউটপুট এর আগে p.WaitforExit কল করে তবে একটি অচলাবস্থার পরিণতি ঘটতে পারে e রিডটোইন্ড এবং শিশু প্রক্রিয়া পুনঃনির্দেশিত স্ট্রিমটি পূরণ করার জন্য পর্যাপ্ত পাঠ্য লেখায়। সন্তানের প্রক্রিয়াটি প্রস্থান করার জন্য পিতামাতার প্রক্রিয়া অনির্দিষ্টকালের জন্য অপেক্ষা করবে। সন্তানের প্রক্রিয়াটি সম্পূর্ণ স্ট্যান্ডার্ডআউটপুট স্ট্রিম থেকে পিতামাতার পড়ার জন্য অনির্দিষ্টকালের জন্য অপেক্ষা করবে।

আপনি যখন স্ট্যান্ডার্ড আউটপুট এবং স্ট্যান্ডার্ড ত্রুটি স্ট্রিম উভয় থেকে সমস্ত পাঠ্য পড়েন তখন একইরকম সমস্যা রয়েছে। উদাহরণস্বরূপ, নিম্নলিখিত সি # কোড উভয় স্ট্রিমে একটি রিড অপারেশন সম্পাদন করে।

কোডটি এতে রূপান্তরিত করে;

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "sqlplus";
p.StartInfo.Arguments = string.Format("xxx/xxx@{0} @{1}", in_database, s);

bool started = p.Start();
// important ... read stream input before waiting for exit.
// this avoids deadlock.
string output = p.StandardOutput.ReadToEnd();

p.WaitForExit();

Console.WriteLine(output);

if (p.ExitCode != 0)
{
    Console.WriteLine( string.Format("*** Failed : {0} - {1}",s,p.ExitCode));
    break;
}

যা এখন সঠিকভাবে প্রস্থান করে।


2
স্ক্যালপ্লাস সম্পর্কিত একটি টিপ: আপনি যদি জানতে চান যে স্ক্রিপ্টের প্রয়োগ কার্যকর হয়েছে কিনা আপনি স্ক্রিপ্টের শুরুতে WHENEVER SQLERROR থেকে প্রস্থান করুন SQL.SQLCODE যুক্ত করতে পারেন। এইভাবে স্ক্যালপ্লাস প্রক্রিয়াটি স্কেরল ত্রুটি নম্বরটি রিটার্ন কোড হিসাবে ফিরিয়ে দেয়।
দেবদিমি

কোন সম্পূর্ণ পূর্ণ উত্স কোড নমুনা? ইন_ড্যাটাবেস কি, এস ??
কিকিনেট

2
এটি আমার পক্ষে কাজ করে না p.StandardOutput.ReadToEnd();কখনই প্রস্থান হয় না
লুই রাইস

2

বিবেচনার জন্য দুটি বিষয় রয়েছে।

1) এই উত্স কোডটি আমার পক্ষে কাজ করেছে:

private static string Execute(string credentials, string scriptDir, string scriptFilename)
{ 
  Process process = new Process();
  process.StartInfo.UseShellExecute = false;
  process.StartInfo.WorkingDirectory = scriptDir;
  process.StartInfo.RedirectStandardOutput = true;
  process.StartInfo.FileName = "sqlplus";
  process.StartInfo.Arguments = string.Format("{0} @{1}", credentials, scriptFilename);
  process.StartInfo.CreateNoWindow = true;

  process.Start();
  string output = process.StandardOutput.ReadToEnd();
  process.WaitForExit();

  return output;
}

আমি ওয়ার্কিং ডিরেক্টরিটি স্ক্রিপ্ট ডিরেক্টরিতে সেট করেছি, যাতে স্ক্রিপ্টের মধ্যে সাব স্ক্রিপ্টগুলিও কাজ করে।

যেমন হিসাবে কল Execute("usr/pwd@service", "c:\myscripts", "script.sql")

2) আপনাকে বিবৃতি দিয়ে আপনার এসকিউএল স্ক্রিপ্ট চূড়ান্ত করতে হবে EXIT;


1

সত্তা ফ্রেমওয়ার্ক ব্যবহার করে আপনি এর মতো সমাধান নিয়ে যেতে পারেন। আমি এই কোডটি ই 2 টি পরীক্ষা শুরু করার জন্য ব্যবহার করি। এসকিএল ইনজেকশন আক্রমণগুলি প্রতিরোধ করতে, ব্যবহারকারীর ইনপুটের ভিত্তিতে এই স্ক্রিপ্টটি তৈরি না করা বা এর জন্য কমান্ড প্যারামিটার ব্যবহার না করা নিশ্চিত করুন (পরামিতিগুলি গ্রহণ করে এক্সিকিউটসকিএলকম্যান্ডের ওভারলোড দেখুন)।

public static void ExecuteSqlScript(string sqlScript)
{
    using (MyEntities dataModel = new MyEntities())
    {
        // split script on GO commands
        IEnumerable<string> commands = 
            Regex.Split(
                sqlScript, 
                @"^\s*GO\s*$",
                RegexOptions.Multiline | RegexOptions.IgnoreCase);

        foreach (string command in commands)
        {
            if (command.Trim() != string.Empty)
            {
                dataModel.Database.ExecuteSqlCommand(command);
            }
        }              
    }
}

-1

আমি এটি করার কোনও সঠিক এবং বৈধ উপায় খুঁজে পাইনি। তাই পুরো দিন পরে, আমি বিভিন্ন উত্স থেকে প্রাপ্ত এই মিশ্র কোডটি নিয়ে এসেছি এবং কাজটি করার চেষ্টা করছি।

তবে এটি এখনও একটি ব্যতিক্রম উত্পন্ন করছে ExecuteNonQuery: CommandText property has not been Initializedযদিও এটি স্ক্রিপ্ট ফাইলটি সাফল্যের সাথে চালায় - আমার ক্ষেত্রে এটি সফলভাবে ডাটাবেস তৈরি করে এবং প্রথম প্রারম্ভে ডেটা সন্নিবেশ করে।

public partial class Form1 : MetroForm
{
    SqlConnection cn;
    SqlCommand cm;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        if (!CheckDatabaseExist())
        {
            GenerateDatabase();
        }
    }

    private bool CheckDatabaseExist()
    {
        SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=SalmanTradersDB;Integrated Security=true");
        try
        {
            con.Open();
            return true;
        }
        catch
        {
            return false;
        }
    }

    private void GenerateDatabase()
    {

        try
        {
            cn = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=master;Integrated Security=True");
            StringBuilder sb = new StringBuilder();
            sb.Append(string.Format("drop databse {0}", "SalmanTradersDB"));
            cm = new SqlCommand(sb.ToString() , cn);
            cn.Open();
            cm.ExecuteNonQuery();
            cn.Close();
        }
        catch
        {

        }
        try
        {
            //Application.StartupPath is the location where the application is Installed
            //Here File Path Can Be Provided Via OpenFileDialog
            if (File.Exists(Application.StartupPath + "\\script.sql"))
            {
                string script = null;
                script = File.ReadAllText(Application.StartupPath + "\\script.sql");
                string[] ScriptSplitter = script.Split(new string[] { "GO" }, StringSplitOptions.None);
                using (cn = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=master;Integrated Security=True"))
                {
                    cn.Open();
                    foreach (string str in ScriptSplitter)
                    {
                        using (cm = cn.CreateCommand())
                        {
                            cm.CommandText = str;
                            cm.ExecuteNonQuery();
                        }
                    }
                }
            }
        }
        catch
        {

        }

    }

}

আমি এটি করার কোনও সঠিক এবং বৈধ উপায় খুঁজে পাইনি। তাই পুরো দিন পরে, আমি বিভিন্ন উত্স থেকে প্রাপ্ত এই মিশ্র কোডটি নিয়ে এসেছি এবং কাজটি করার চেষ্টা করছি। তাই আমি তাদের সবগুলিকে একীভূত করে ফলাফলটি দিয়েছি। তবে এটি এখনও "এক্সিকিউটননকুইয়ারি: কমান্ডটেক্সট সম্পত্তি শুরু করা হয়নি" ব্যতিক্রম উত্পন্ন করছে। যদিও এটি সফলভাবে স্ক্রিপ্ট ফাইলটি চালায় (আমার ক্ষেত্রে, সাফল্যের সাথে ডাটাবেস তৈরি করুন এবং প্রথম সূচনায় ডেটা inোকান)।
মুহাম্মদ সালমান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.