Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C脚本在运行下一步之前未完成SQL查询_C#_Tableadapter - Fatal编程技术网

C# C脚本在运行下一步之前未完成SQL查询

C# C脚本在运行下一步之前未完成SQL查询,c#,tableadapter,C#,Tableadapter,我有一个c脚本,它作为更大代码的一部分运行。它应该执行一个sql脚本,然后通过SFTP连接发送生成的.csv文件 问题在于,查询似乎是在执行完查询之前发送数据的。在我的程序进行下一步之前,是否有办法确保查询已完成 下面是这篇文章的SQL部分的代码 using System; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace SQLtoCSV { static cla

我有一个c脚本,它作为更大代码的一部分运行。它应该执行一个sql脚本,然后通过SFTP连接发送生成的.csv文件

问题在于,查询似乎是在执行完查询之前发送数据的。在我的程序进行下一步之前,是否有办法确保查询已完成

下面是这篇文章的SQL部分的代码

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace SQLtoCSV
{
    static class SQL
    {
        public static DataTable GetData(string strQuery)
        {
            var cmd = new SqlCommand(strQuery);
            var dt = new DataTable();
            var strConnString = ConfigurationManager.ConnectionStrings["RSConString"].ConnectionString;
            Logger.WriteLog("Used RS connection string: {0}", strConnString);
            var con = new SqlConnection(strConnString);
            var sda = new SqlDataAdapter();
            cmd.CommandType = CommandType.Text;
            cmd.CommandTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["RSTimeout"]);
            cmd.Connection = con;
            try
            {
                con.Open();
                sda.SelectCommand = cmd;
                sda.Fill(dt);
                return dt;
            }
            catch (Exception ex)
            {
                Logger.WriteLog("SQL GetData trown exception, see next entry.");
                Logger.WriteLog(ex);
                return null;
            }
            finally
            {
                con.Close();
                sda.Dispose();
                con.Dispose();
            }
        }
    }
}
这里是主控制流

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.IO;

namespace SQLtoCSV
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string sourceDirectory = ConfigurationManager.AppSettings["LocalSQLdirectory"].ToString();
                List<string> txtFiles = Directory.EnumerateFiles(sourceDirectory, "*.sql", SearchOption.AllDirectories).ToList();

                Logger.WriteLog("Found {0} SQL files in local dir '{1}'.", txtFiles.Count, sourceDirectory);

                foreach (string currentFile in txtFiles)
                {
                    string strSql = File.ReadAllText(currentFile);
                    Logger.WriteLog("Executing '{0}'...", currentFile);
                    var dtTable = SQL.GetData(strSql);
                    Logger.WriteLog("Done.");
                    var tmpFile = currentFile + ".tmp";
                    TableToCSV.ConvertDtTableToCSV(dtTable, tmpFile);
                    var name = Path.GetFileNameWithoutExtension(currentFile);
                    SFTP.upload(tmpFile, name);
                    File.Delete(tmpFile);
                }
            }
            catch (Exception ex)
            {
                Exception exMail = null;
                Logger.WriteLog("The main app trown exception, see next entry");
                try
                {
                    var msg = "CSV to SQL application thrown exception: \r\n" +
                              "\tSource: " + ex.Source + "\r\n" +
                              "\tMessage: " + ex.Message + "\r\n" +
                              "Stack: \r\n" + ex.StackTrace + "\r\n";
                    if (ex.InnerException != null)
                    {
                        msg += "Inner exception: \r\n" +
                               "\tSource: " + ex.InnerException.Source + "\r\n" +
                               "\tMessage: " + ex.InnerException.Message + "\r\n" +
                               "\tStack: " + ex.InnerException.StackTrace + "\r\n";
                    }
                    MailHelper.Send_Mail(msg, "SQL to CSV error");

                }
                catch(Exception ex2) {
                    exMail = ex2;
                }
                Logger.WriteLog(ex);
                if (exMail != null)
                {
                    Logger.WriteLog("Cannot send a mail, see next entry");
                    Logger.WriteLog(exMail);
                }
            }
        }
    }
}

好的,CSV部分是您的问题。默认情况下,StreamWriter是缓冲的,因此您的最后一块数据很可能不会写入磁盘。添加sw.Flush;在您结束像这样使用语句之前:

    public static void ConvertDtTableToCSV(DataTable dt, string filePath)
    {
        string tempPath = System.IO.Path.GetTempPath();

        using (var sw = new StreamWriter(filePath, false, Encoding.UTF8))
        {
            var columnNames = dt.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
            sw.WriteLine(string.Join(",", columnNames));

            foreach (DataRow row in dt.Rows)
            {
                IEnumerable<string> fields = row.ItemArray.Select(field => /*string.Concat("\"", */field.ToString()/*.Replace("\"", "\"\""), "\"")*/);
                sw.WriteLine(string.Join(",", fields));
            }
            sw.Flush();
        }
    }

我不想这么说,但是代码本身是正确的,尽管缺少flush部分。也就是说,问题出在配置文件上,导致数据从测试环境而不是生产环境中提取

由于两者的结果集通常是镜像的,因此发现它们之间存在细微的差异。我想这个故事的寓意是,如果你看到的是与你所看到的理论图景不相符的非常奇怪的结果,那么退一步,确保基础是正确的是值得的


感谢所有帮助过我的人

您看到了什么使您认为查询在执行之前发送了数据?是否有更多的代码可以准确地显示您看到的内容?例如,您提到的下一步是哪行代码?保存数据的部分在哪里?你的意思是sda.Filldt在返回dt时没有完成吗?我将把主控制流发布到原始comment.G_P中。为了澄清,我怀疑脚本以某种方式切断了临时文件。我手动运行查询时得到的数据约为1gig;通过脚本发送的文件约占其中的20%。因此,要么是以更高效的格式保存,要么不是所有的数据都进入了文件。您是否调试了它,并在返回时检查了dtTable中的行数?我几乎更倾向于说,在您的代码中生成csv而不是SQL部分。遗憾的是,这让我得到了与之前截取文件相同的最终结果。这似乎是一个愚蠢的问题,但这可能是对tmp文件大小的限制,从而阻止所有数据进入吗?哦,等等,您是在查看temp文件还是FTP文件,以获取所看到的行数。你用什么FTP文件?我添加了SFTP部分,你可以看一下。我不认为我关于tmp文件大小的理论是正确的,因为我可以手动推到.tmp并获得正确的数据量。我们将删除临时文件的那一行注释掉并检查它。或者将其设置为在其他地方手动写出。不过,您的FTP代码也缺少刷新。
using System;
using System.Configuration;
using Renci.SshNet;
using System.IO;

namespace SQLtoCSV
{
    static class SFTP
    {
        public static void upload(string tmpFile, string fileName)
        {
            try
            {
                var host = ConfigurationManager.AppSettings["SFTPhost"].ToString();
                var port = Convert.ToInt32(ConfigurationManager.AppSettings["SFTPport"]);
                var username = ConfigurationManager.AppSettings["SFTPuser"].ToString();
                var password = ConfigurationManager.AppSettings["SFTPpassword"].ToString();
                var workingdirectory = ConfigurationManager.AppSettings["SFTPdirectory"].ToString();
                var fileExtension = ConfigurationManager.AppSettings["UploadedFileExtension"].ToString();
                var timeout = Convert.ToInt32(ConfigurationManager.AppSettings["SFTPtimeout"]);
                var timestamp = ConfigurationManager.AppSettings["SFTPtimestamp"].ToString();

                fileName += DateTime.Now.ToString(timestamp) + ".csv";

                using (var client = new SftpClient(host, port, username, password))
                {
                    client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(timeout);
                    client.Connect();
                    Logger.WriteLog("Connected to {0}", host);

                    client.ChangeDirectory(workingdirectory);
                    Logger.WriteLog("Changed directory to {0}", workingdirectory);

                    using (var fileStream = new FileStream(tmpFile, FileMode.Open))
                    {
                        Logger.WriteLog("Uploading {0} ({1:N0} bytes)", fileName, fileStream.Length);

                        // bypass Payload error large files
                        client.BufferSize = 4 * 1024;
                        client.UploadFile(fileStream, fileName);
                    }
                }
                Logger.WriteLog("The file '{0}' is uploaded");
            }
            catch(Exception ex)
            {
                Logger.WriteLog("The SFTP.upload function trown exception, see next entry");
                Logger.WriteLog(ex);
                throw;
            }
        }

        private static Stream StreamFromString(string s)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }
    }
}
    public static void ConvertDtTableToCSV(DataTable dt, string filePath)
    {
        string tempPath = System.IO.Path.GetTempPath();

        using (var sw = new StreamWriter(filePath, false, Encoding.UTF8))
        {
            var columnNames = dt.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
            sw.WriteLine(string.Join(",", columnNames));

            foreach (DataRow row in dt.Rows)
            {
                IEnumerable<string> fields = row.ItemArray.Select(field => /*string.Concat("\"", */field.ToString()/*.Replace("\"", "\"\""), "\"")*/);
                sw.WriteLine(string.Join(",", fields));
            }
            sw.Flush();
        }
    }