C# SQL Command .Fill занимает слишком много времени при вызове сервера Firebird, присоединяется к таблице с хранимой процедурой

Я пытаюсь сбросить данные из базы данных Firebird SQL 2.5 с небольшим успехом или безуспешно, потому что я пытаюсь объединить таблицу и хранимую процедуру. Код, представляющий проблемный запрос, следующий:

select
    U.SYMBOL
    , '0' AS FIRM_ID
    , U.DATA_OD AS DATA
    , IIF(EXTRACT(DAY FROM U.DATA_OD) = 1 AND EXTRACT(MONTH FROM U.DATA_OD) = 1, 'NR', 'ZW') AS PRZYCZYNA_ZMIANY_WYM
    , PS.WYMIAR AS WYMIAR
    , PS.ZALEGLY AS WYM_ZAL
    , ' ' AS WYMIAR_INW
    , ' ' AS WYMIAR_INW_ZAL
    , ' ' AS NAZWA_ABSENCJI
from 
    P_PRA_WYM_URL U
    left JOIN PS_WYK_URLOPOW(U.SYMBOL, U.DATA_OD, U.DATA_OD) ps ON 1=1
where
    U.SYMBOL IN (SELECT SYMBOL FROM P_PRACOWNIK)

В PS_WYK_URLOPOWхранимая процедура принимает три параметра: номер сотрудника и две даты. Все параметры являются членамиP_PRA_WYM_URLtable, поэтому хранимая процедура должна выполняться один раз для каждой записи в этой таблице. В этой таблице более 40 000 записей.

Я выполняю этот запрос, используя следующий код C#:

if (AreSettingsPopulated())
            {
                string sFilepath = dSettings[FILEPATHKEY];
                string sUsername = dSettings[USERNAMEKEY];
                string sPassword = Encoding.UTF8.GetString(System.Convert.FromBase64String(dSettings[DBPASSWORDKEY]));

                string connectionString =
                                    "User={0};" +
                                    "Password={1};" +
                                    "Database={2};" +
                                    "DataSource=localhost;" +
                                    "Port=3050;" +
                                    "Dialect=1;" +
                                    "Charset=NONE;" +
                                    "Role=;" +
                                    "Connection lifetime=15;" +
                                    "Pooling=true;" +
                                    "MinPoolSize=0;" +
                                    "MaxPoolSize=50;" +
                                    "Packet Size=8192;" +
                                    "ServerType=0";

                FbConnection fbConn = null;

                try
                {
                    string sSqlQuery = "";

                    using (FileStream fs = new FileStream(string.Format("{0}.sql", dSettings[TABLENAMEKEY]), FileMode.Open))
                    {
                        using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
                        {
                            if (!sr.EndOfStream)
                                sSqlQuery = sr.ReadToEnd();
                            sr.Close();
                        }
                        fs.Close();
                    }

                    if (sSqlQuery != "")
                    {
                        DataTable dtDumpResults = new DataTable(dSettings[TABLENAMEKEY]);

                        fbConn = new FbConnection(string.Format(connectionString, sUsername, sPassword, sFilepath));
                        FbCommand fbcDumpCommand = new FbCommand(sSqlQuery, fbConn);
                        fbcDumpCommand.CommandTimeout = 90000000;

                        if (fbConn.State != System.Data.ConnectionState.Open)
                            fbConn.Open();

                        using (FbDataAdapter fbdaDumpCommand = new FbDataAdapter(sSqlQuery, fbConn))
                        {
                            this.engine.WriteLine("Dumping the contents from database...");
                            fbdaDumpCommand.Fill(dtDumpResults);
                            this.engine.WriteLine("Dump complete!");
                        }

                        if (dtDumpResults.Rows.Count > 0)
                        {
                            GenerateExportXlsFile(dtDumpResults, dSettings[TABLENAMEKEY]);
                        }
                        else
                            throw new ArgumentNullException("The result set returned null!");
                    }
                    else
                        throw new ArgumentNullException("The SQL query is empty!");
                }
                catch (Exception ex)
                {
                    return string.Format("Error while invoking plugin: {0}", ex.ToString());
                }
                finally
                {
                    if (fbConn != null && fbConn.State == System.Data.ConnectionState.Open)
                        fbConn.Close();
                }
            }
            else
                return "Execution failed! The settings are not populated!";

            return string.Format("Export of table {0} complete!", dSettings[TABLENAMEKEY]);
        }

Если я попытаюсь сбросить данные с помощью запроса, показанного выше, с помощью Flamerobin, механизм предварительной выборки будет работать и загружать данные каждые 500 записей, и я могу получить полный дамп, в то время как с приложением C# выполнение останавливается на fbdaDumpCommand.Fill(dtDumpResults); шаг.

Возникает вопрос: как оптимизировать запрос, чтобы он работал внутри приложения C#?

0 ответов

Другие вопросы по тегам