4

次のような問題があり
ます。1。C#ASP.Netを使用してMySQLからデータを取得します。--完了
--2。No.1のすべてのデータがAS400のテーブルに挿入されます。-このステップでエラーが発生しました-

エラーメッセージに次のように表示されERROR [42000] [IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0104 - Token ; was not valid. Valid tokens: <END-OF-STATEMENT>.ます。クエリを相互に区切るためにセミコロンを使用したのは事実ですが、許可されていません。グーグルをしましたが、解決策が見つかりません。
私の質問は<END-OF-STATEMENT>、そのエラーメッセージの意味は何ですか..?
これが私のソースコードです。

private static void doInsertDOCADM(MySqlConnection conn)
    {
        // Get Temporary table
        String query = "SELECT * FROM TB_T_DOC_TEMPORARY_ADM";
        DataTable dt = CSTDDBUtil.ExecuteQuery(query);

        OdbcConnection as400Con = null;
        as400Con = CSTDDBUtil.GetAS400Connection();
        as400Con.Open();

        if (dt != null && dt.Rows.Count > 0)
        {
            int counter = 1, maxInsertLoop = 50;

            using (OdbcCommand cmd = new OdbcCommand())
            {
                cmd.Connection = as400Con;

                foreach (DataRow dr in dt.Rows)
                {
                    cmd.CommandText += "INSERT INTO DCDLIB.WDFDOCQ VALUES " + "(?,?,?,?);";

                    cmd.Parameters.Add("1", OdbcType.VarChar).Value = dr["PROD_MONTH"].ToString();
                    cmd.Parameters.Add("2", OdbcType.VarChar).Value = dr["NEW_MAIN_DEALER_CD"].ToString();
                    cmd.Parameters.Add("3", OdbcType.VarChar).Value = dr["MODEL_SERIES"].ToString();
                    cmd.Parameters.Add("4", OdbcType.VarChar).Value = dr["MODEL_CD"].ToString();


                    if (counter < maxInsertLoop)
                    {
                        counter++;
                    }
                    else
                    {
                        counter = 1;
                        cmd.ExecuteNonQuery();
                        cmd.CommandText = "";
                        cmd.Parameters.Clear();
                    }
                }

                if (counter > 1) cmd.ExecuteNonQuery();
            }
        }

注:アプリケーションのパフォーマンスを向上させるために、この方法を使用しました(最初にいくつかのクエリを収集してから、それらのクエリを実行します)。

4

2 に答える 2

6

Clockwork-Museが指摘したように、問題は、コマンドで実行できるSQLステートメントは1つだけであるということです。iSeriesサーバーは、一度に複数のステートメントを処理しません。

iSeriesサーバーがV6R1以降を実行している場合は、ブロック挿入を使用して複数の行を挿入できます。ODBCドライバーを使用して実行できるかどうかはわかりませんが、クライアントアクセスを使用しているため、iSeriesADO.NETドライバーをインストールできるはずです。ADO.NETiSeriesドライバーとODBCドライバーの間に多くの違いはありませんが、ADO.NETを使用すると、iSeries固有の機能にアクセスできます。

ADO.NETドライバーを使用すると、複数の挿入が次のような単純な問題になります。

    using (iDB2Connection connection = new iDB2Connection(".... connection string ..."))
        {
            // Create a new SQL command
            iDB2Command command = 
                new iDB2Command("INSERT INTO MYLIB.MYTABLE VALUES(@COL_1, @COL_2", connection);

            // Initialize the parameters collection
            command.DeriveParameters();

            // Insert 10 rows of data at once
            for (int i = 0; i < 20; i++)
            {
                // Here, you set your parameters for a single row
                command.Parameters["@COL_1"].Value = i;
                command.Parameters["@COL_2"].Value = i + 1;
                // AddBatch() tells the command you're done preparing a row
                command.AddBatch();
            }

            // The query gets executed
            command.ExecuteNonQuery();
        }
    }

VB6とODBCを使用してブロック挿入を行うためにIBMから提供された参照コードもいくつかありますが、.NETに簡単に移植できるかどうかはわかりません:http://publib.boulder.ibm.com/infocenter/iseries/v5r4 /index.jsp?topic=%2Frzaik%2Frzaikextfetch.htm

お役に立てば幸いです。

于 2012-10-05T08:05:26.720 に答える
2

それが言うとき、それはそれが言う<END-OF-STATEMENT>ことについて意味します-それは実行されたステートメントの終わりであることを望んでいます。AS / 400が実行ユニットごとに複数のステートメントを許可するかどうかは覚えていませんが(まったく)、ここでは明らかに機能していません。そして、ドライバーもそれを扱っていません。

実際、あなたにはもっと大きく、もっと根本的な問題があります。具体的には、一度に1行ずつ実行INSERTします(通常、行ごとの苦悶行として知られています)。DB2では、VALUES句内の行のコンマ区切りリスト(so、INSERT INTO <table_name> VALUES(<row_1_columns>), (<row_2_columns>))が許可されています-使用しているドライバーでは、配列(行全体または列ごと)を提供できますか?それ以外の場合は、このようなものに抽出/ロードユーティリティを使用することを検討してください-これによりプロセスが高速化されることを保証できます。

于 2012-10-04T15:46:10.437 に答える