.NET程序连接Oracle一次执行多行SQL的注意事项

以前写的基于MSSQL数据库的.NET程序,不用担心SQL语句中的;或者换行符。但是因为要基于Infor LN的Oracle数据库进行开发,就碰到了;分号和换行的报错,同时一次执行UPDATE的多条更新语句时,也会报错。

Oracle.ManagedDataAccess.Client.OracleException:ORA-00911: invalid character

单行SQL如果有换行时,加了;就报上面的错,多行执行的时候,会报下面这种错误

Oracle.ManagedDataAccess.Client.OracleException:ORA-06550: line 1, column 1:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

   ; <an identifier> <a double-quoted delimited-identifier>
The symbol ";" was substituted for "end-of-file" to continue.

虽然从网上能搜索到ExecuteNonQuery执行Oracle多条SQL的时候需要用到以下结构

BEGIN
SQL1;
SQL2;
SQL3;
END;

但是并没有人提到一定要确保整个SQL是一行,必须没有换行!

BEGIN
 UPDATE BAANDB.TWHINH225301 A
 SET A.T$WVID = -999
,A.T$ASGN = 1
,A.T$PKID = 'Troy'
,A.T$STLO = 'EMS'
 WHERE A.T$RUNN = 'CN432789'
 AND A.T$PICM = 1
 AND A.T$ASGN = 2
 AND A.T$PCKD = 2;
UPDATE BAANDB.TWHINH225301 A
 SET A.T$WVID = -999
,A.T$ASGN = 1
,A.T$PKID = 'Troy'
,A.T$STLO = 'EMS'
 WHERE A.T$RUNN = 'CN432785'
 AND A.T$PICM = 6
 AND A.T$ASGN = 2
 AND A.T$PCKD = 2;
END;

因为写日志看SQL方便,用了AppendLine,那么下面的代码中,需要手动替换下换行符:Replace(Environment.NewLine, ” “),如果还不放心,可以用Replace(“r\n”, ” “).Replace(‘\n’, ‘ ‘).Replace(‘\r’, ‘ ‘) 批量将各种换行符替换为空格。

            var result = 1;
            var sb = new StringBuilder();
            sb.AppendLine("BEGIN");
            foreach (var entity in list)
            {
                sb.AppendLine("UPDATE BAANDB.TWHINH225" + companyId + " A");
                sb.AppendLine("SET A.T$WVID = -999");
                sb.AppendLine(",A.T$ASGN = 1");
                if (!string.IsNullOrEmpty(entity.Picker))
                {
                    entity.Picker = dbHelper.SqlSafe(entity.Picker);
                    sb.AppendLine(",A.T$PKID = '" + entity.Picker + "'");
                }
                if (!string.IsNullOrEmpty(entity.StagingLocation))
                {
                    entity.StagingLocation = dbHelper.SqlSafe(entity.StagingLocation);
                    sb.AppendLine(",A.T$STLO = '" + entity.StagingLocation + "'");
                }
                // By Line
                sb.AppendLine("WHERE A.T$OORG = " + GetOrderOrigin(entity.OrderOrigin));
                sb.AppendLine("AND A.T$ORNO = '" + entity.OrderNumber + "'");
                sb.AppendLine("AND A.T$OSET = " + entity.OrderSet);
                sb.AppendLine("AND A.T$PONO = " + entity.Line);
                sb.AppendLine("AND A.T$SEQN = " + entity.SequenceNumber);
                sb.AppendLine("AND A.T$SERN = " + entity.Advice);
                // Check Assign Status
                sb.AppendLine("AND A.T$ASGN = 2");
                sb.AppendLine("AND A.T$PCKD = 2;");
            }
            sb.AppendLine("END;");
            try
            {
                ExecuteNonQuery(sb.ToString().Replace(Environment.NewLine, " "));
            }
            catch (Exception e)
            {
                LogUtil.WriteException(e);
                result = 0;
            }

            return result;

因为这个问题,还从大石头的新生命微信群发了红包求助,意外收获了结识了一个挺不错的开发者王振(王Bank)和他写的DbHelper:https://gitee.com/wangbank/BankDbHelper

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据