首页 新闻 会员 周边 捐助

拼接批量sql更新问题

0
悬赏园豆:10 [已解决问题] 解决于 2012-06-28 10:54

想请教园里各位大虾们,我在后台批量拼接sql语句以分号分隔,更新到oracle,出现无效字符的错误,各位有没有好的解决办法(我试过加begin end或者换行都没有用,但不加这个分号也报错。╮(╯▽╰)╭,蛋疼),这个问题困扰我好久了,麻烦帮忙解决下,谢谢!下面是主要方法代码:

public static bool InsertBatchSim_Info(DataTable dt)
        {
            int tag = 0;
            if (dt != null && dt.Rows.Count > 0)
            {
                try
                {
                    StringBuilder sql = new StringBuilder();
                    using (OracleConnection conn = new OracleConnection(DBSettings.ConnectionString))
                    {
                        OracleCommand cmd = new OracleCommand();
                        cmd.CommandType = CommandType.Text;

                        for (int i = 0; i < dt.Rows.Count; i++)
                        {
                            if (i == 0 || i % 200 != 0)
                            {
                                sql.AppendLine(@"insert into icka_simcard_info
                                        (sim_phone, sim_no, flow_rate, create_time, sim_apn, sim_company)
                                        values
                                        ('" + dt.Rows[i]["sim_phone"] + "', '" + dt.Rows[i]["sim_no"] + "', '" + dt.Rows[i]["flow_rate"] + "', sysdate, '" + dt.Rows[i]["sim_apn"] + "', '" + dt.Rows[i]["sim_company"] + "');");

                                if (i < dt.Rows.Count)
                                {
                                    continue;
                                }
                                else
                                {
                                    cmd.CommandText = sql.ToString();
                                    tag = DAHelper.ExecuteNonQuery(conn, cmd);
                                    sql.Clear();
                                }
                            }
                            else
                            {
                                sql.AppendLine(@"insert into icka_simcard_info
                                        (sim_phone, sim_no, flow_rate, create_time, sim_apn, sim_company)
                                        values
                                        ('" + dt.Rows[i]["sim_phone"] + "', '" + dt.Rows[i]["sim_no"] + "', '" + dt.Rows[i]["flow_rate"] + "', sysdate, '" + dt.Rows[i]["sim_apn"] + "', '" + dt.Rows[i]["sim_company"] + "');");
                                cmd.CommandText = sql.ToString();
                                tag = DAHelper.ExecuteNonQuery(conn, cmd);
                                sql.Clear();

                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    tag = 0;
                }

            }
            return tag > 0 ? true : false;;
        }
活在當下的主页 活在當下 | 初学一级 | 园豆:186
提问于:2012-06-27 11:18
< >
分享
最佳答案
1

试试在分号之后加上\n

收获园豆:10
dudu | 高人七级 |园豆:29732 | 2012-06-27 11:38

是在分号后面加吗,还是不行列,提示无效字符!

活在當下 | 园豆:186 (初学一级) | 2012-06-27 11:43

代码我贴上来了,麻烦你看下!

活在當下 | 园豆:186 (初学一级) | 2012-06-28 09:55

@活在當下: 建议代码加上着色

dudu | 园豆:29732 (高人七级) | 2012-06-28 10:04

@dudu: ╮(╯▽╰)╭,有没有好的方法着色?

活在當下 | 园豆:186 (初学一级) | 2012-06-28 10:08

@活在當下: 点击编辑器中最右边的一个按钮

dudu | 园豆:29732 (高人七级) | 2012-06-28 10:16

@活在當下: 建议将 sql.ToString(); 的结果保存到文件中,然后将文件中的SQL复制到pl/sql中执行一下试试

dudu | 园豆:29732 (高人七级) | 2012-06-28 10:22

@dudu: 这个我测试过了,可以通过,我很不解,我记得sqlserver是支持在后台拼接用分号的,但oracle就是不行。

活在當下 | 园豆:186 (初学一级) | 2012-06-28 10:26

@活在當下: 找到答案了,是OracleCommmand不支持执行多条SQL语句。

An OracleCommmand can run only 1 sql or plsql statement at a time. There is no need of separating multiple statements.

The semicolon is part of documentation to divide multiple statements. It is not part of the single DDL statement. For an OracleCommand there is no need to append a semicolon because it can only handle one statement at a time.

答案来自:why the semicolon couldn't place in the CommandText of a OracleCommand when C#

dudu | 园豆:29732 (高人七级) | 2012-06-28 10:35

@dudu: 感谢dudu,O(∩_∩)O~,这个问题困扰我N久了,看来我还得好好补补En文了!

活在當下 | 园豆:186 (初学一级) | 2012-06-28 10:55
其他回答(3)
0

分号也是Oracle的结束符

最好检查下你拼接之后的SQL语句是否有错误

再来组织拼接

分号 is ;

冒号 is :

难道我眼瞎了

澜紫癜青 | 园豆:313 (菜鸟二级) | 2012-06-27 11:27

这个是没有问题的,我单独放到pl/sql中执行,是可以成功的。不知道为什么c#不支持这个分号。

支持(0) 反对(0) 活在當下 | 园豆:186 (初学一级) | 2012-06-27 11:30

@活在當下: 

最好是贴下代码,而且话不要说的太绝对了。

支持(0) 反对(0) 澜紫癜青 | 园豆:313 (菜鸟二级) | 2012-06-27 11:31

@澜紫癜青: 

sql.AppendLine(@"insert into icka_simcard_info
(sim_phone, sim_no, flow_rate, create_time, sim_apn, sim_company, status)
values
(:v_sim_phone, :v_sim_no, :v_flow_rate, sysdate, :v_sim_apn, :v_sim_company, :v_status);");

这个是主要的拼接代码! 这个是放在一个循环里面的,大概两百条执行一次这样!

支持(0) 反对(0) 活在當下 | 园豆:186 (初学一级) | 2012-06-27 11:34

@活在當下: 

我眼瞎了,

分号 is ;

冒号 is :

你贴的代码是冒号,不是分号!!!

而且是单句,未见到批量这个概念

而且你这语法是PLSQL以及Oracle的SQLPLUS里的

和C#无关

"insert into icka_simcard_info (sim_phone, sim_no, flow_rate, create_time, sim_apn, sim_company, status)values (:v_sim_phone, :v_sim_no, :v_flow_rate, sysdate, :v_sim_apn, :v_sim_company, :v_status);"

:v_sim_phone之类的可以直接改为变量,这个跟SQL拼接木有关系

 

给你修改后的代码

string sqlString = "insert into icka_simcard_info\n" +
"  (sim_phone, sim_no, flow_rate, create_time, sim_apn, sim_company, status)\n" +
"values\n" +
"  (:v_sim_phone,\n" +
"   :v_sim_no,\n" +
"   :v_flow_rate,\n" +
"   sysdate,\n" +
"   :v_sim_apn,\n" +
"   :v_sim_company,\n" +
"   :v_status);";

 

如果有大量SQL语句,建议使用存储过程,oracle里叫包,或者使用Oracle数据库事务,这样可以减轻服务器压力

支持(0) 反对(0) 澜紫癜青 | 园豆:313 (菜鸟二级) | 2012-06-27 11:40

@澜紫癜青: 是分号,可能是显示有问题。我那样在变量前面加上冒号,是通过Parameter方法赋值的,我是通过StringBuilder.AppendLine方法来拼接的,应该默认会换行的吧!

支持(0) 反对(0) 活在當下 | 园豆:186 (初学一级) | 2012-06-27 11:49

@活在當下: 

不懂了,你一会说拼接SQL语句,一会说Parameter方法赋值
如果不贴出完整代码,真不懂你是表达啥意思

如果有大量SQL语句,建议使用存储过程,或者使用Oracle数据库事务

支持(0) 反对(0) 澜紫癜青 | 园豆:313 (菜鸟二级) | 2012-06-27 11:55

@澜紫癜青: 代码我贴上来了,麻烦你看下!

支持(0) 反对(0) 活在當下 | 园豆:186 (初学一级) | 2012-06-28 09:53
0

批量,如果有是循环AppendLine建议不要使用Parameter,这样会出现,添加相同数据的错误

亡灵法师88 | 园豆:215 (菜鸟二级) | 2012-06-27 17:54

恩,我也发现这个问题了!

支持(0) 反对(0) 活在當下 | 园豆:186 (初学一级) | 2012-06-28 09:10
0

批量SQL中不能有回车符号,AppendLine==>Append

博爸 | 园豆:220 (菜鸟二级) | 2012-06-27 20:50

这个貌似跟换行没有太大关系,主要是分号的问题。

支持(0) 反对(0) 活在當下 | 园豆:186 (初学一级) | 2012-06-28 09:15

@活在当下: 

AppendLine会添加回车符号。下面这样绝对可行:

sql.Append("begin ");

sql.Append("insert into ...;");

...

sql.Append(" end;");

支持(1) 反对(0) 博爸 | 园豆:220 (菜鸟二级) | 2012-06-28 20:54

@shalongbus: 谢了,这个方法确实可行!不够可惜了,你早点回答,我就给你分嘛,O(∩_∩)O哈哈~

支持(0) 反对(0) 活在當下 | 园豆:186 (初学一级) | 2012-06-29 18:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册