4

我有这样的问题:
1. 我使用 C# ASP .Net 从 MySQL 检索数据。-- 完成 --
2. 来自 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 语句。iSeries 服务器不会一次处理多个语句。

如果您的 iSeries 服务器正在运行 V6R1 或更高版本,您可以使用块插入来插入多行。我不确定您是否可以通过 ODBC 驱动程序来做到这一点,但由于您有 Client Access,您应该能够安装 iSeries ADO.NET 驱动程序。ADO.NET iSeries 驱动程序和 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();
        }
    }

IBM 还提供了一些参考代码来使用 VB6 和 ODBC 进行块插入,但我不确定它是否可以轻松移植到 .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 是否允许每个执行单元(完全)有多个语句,但显然它在这里不起作用。司机也没有处理它。

实际上,你有一个更大、更根本的问题;具体来说,您INSERT一次是一行(通常称为 row-by-agonizing-row)。VALUESDB2 允许在子句 (so, )中使用逗号分隔的行列表INSERT INTO <table_name> VALUES(<row_1_columns>), (<row_2_columns>)- 您使用的驱动程序是否允许您提供数组(整行或每列)?否则,请考虑使用提取/加载实用程序来处理此类问题 - 我可以向您保证,这将加快进程。

于 2012-10-04T15:46:10.437 回答