请教分割字符串的问题

Kevin 2012-12-19 01:04:21
字符串如下,如何分割成为三条SQL呢?
create table table11(c1 string, c2 string);insert into table11(c1, c2) values('1;abdc;e''fg', 'b');insert into table11(c2, c1) values('2', 'z');
...全文
439 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
这种问题实在没什么可讨论的,本身这种操作就不该交给用户,精通SQL规范还好一点,然后用户可能的输入太多,你根本无法控制,即使你分离开来了又怎样?拿什么来判断查询语句的规范性? 你应该开放给用户某些可视化的操作,例如按钮点击执行你的库操作,而这些操作最终由你来实现,用户最多也只是输入写相关的字段信息而已 你那么做,一,不安全;二,不好控制;三,扩展性不强;四,维护频繁
Kevin 2012-12-26
  • 打赏
  • 举报
回复

            string sql = "delete form table11 where c2='1;1''';" + 
                "create table table11(c1 string, c2 string);" + 
                "insert into table11(c1, c2) values('1;abdc;e''fg', 'b');" + 
                "insert into table11(c2, c1) values('er;create table 2', 'z')";


            if (sql.Substring(sql.Length - 1) != ";")
                sql += ";";

            char[] chSQL = sql.ToCharArray();

            bool bFindStr = false;
            int nStart = 0 ;
            for (int i = 0; i < chSQL.Length; i++)
            {
                if (chSQL[i] == '\'')
                {
                    if (!bFindStr)
                        bFindStr = true;
                    else
                    {
                        if (chSQL[i + 1] != '\'')
                            bFindStr = false;
                        else
                            i++;
                    }

                    continue;
                }

                if (!bFindStr && chSQL[i] == ';')
                {
                    Console.WriteLine(sql.Substring(nStart, i - nStart + 1));
                    nStart = i + 1;
                }
            }

            if(bFindStr)
                Console.WriteLine(sql.Substring(nStart));
        }
Kevin 2012-12-26
  • 打赏
  • 举报
回复
楼上的肯定不成,试看如下狗屁的SQL语句: string sql = "delete form table11 where c2='1;1''';" + "create table table11(c1 string, c2 string);" + "insert into table11(c1, c2) values('1;abdc;e''fg', 'b');" + "insert into table11(c2, c1) values('er;create table 2', 'z')";
SadlyCodes 2012-12-20
  • 打赏
  • 举报
回复

//原字符串
private static string strSQL =
@"insert into table11(c1, c2) values('1;abdc;e''fg', 'b');delete table table11(c1 string, c2 string);create table table11(c1 string, c2 string);insert into table11(c1, c2) values('1;abdc;e''fg', 'b');drop table s_user";

//设定以以下字符串开头的子句可以作为独立的语句
private static List<string> lstHeaderWord = new List<string>()
{
"create ",
"delete ",
"insert ",
"drop "
};

private static List<string> lstResult = new List<string>();
static void Main(string[] args)
{
//将原字符串按';'分割,加入结果列表
lstResult.AddRange(split(strSQL, ";"));

//将所有分割结果最后附加';'
for (int i = lstResult.Count - 1; i >= 0; i--)
{
lstResult[i] += ";";
}

//遍历结果列表
for (int i = lstResult.Count - 1; i > 0; i--)
{
//如果语句的开头不是允许的语句开头
if (!startWithHeaderWord(lstResult[i]))
{
//将该条语句附加至上一条语句的末尾
lstResult[i - 1] += lstResult[i];
//删除该条的语句
lstResult.RemoveAt(i);
}
}

//输出结果
foreach (string s in lstResult)
{
Console.WriteLine(s);
}
Console.Read();
}

/// <summary>
/// 指示制定的语句头是否可以作为独立的语句
/// </summary>
/// <param name="sentence"></param>
/// <returns></returns>
static bool startWithHeaderWord(string sentence)
{
foreach (string s in lstHeaderWord)
{
if (sentence.StartsWith(s))
{
return true;
}
}
return false;
}

/// <summary>
/// 纯粹为了简化String.Split(String[],StringSplitOptions)
/// </summary>
/// <param name="sentence"></param>
/// <param name="word"></param>
/// <returns></returns>
static string[] split(string sentence, string word)
{
return sentence.Split(new string[] { word }, StringSplitOptions.RemoveEmptyEntries);
}
-过客- 2012-12-19
  • 打赏
  • 举报
回复
按楼主当前给出的例子和规则,可以这样做
Regex reg = new Regex(@"(?is)(\([^()]*\)|[^;()]+)*;");
MatchCollection mc = reg.Matches(yourStr);
foreach (Match m in mc)
{
   richTextBox2.Text += m.Value + "\n";
}
/*-----输出-----
create table table11(c1 string, c2 string);
insert into table11(c1, c2) values('1;abdc;e''fg', 'b');
insert into table11(c2, c1) values('2', 'z');
*/
如果()有嵌套的话,也可以做,只不过正则复杂一些 以上只是针对相对简单的情况,SQL有些情况下还是比较复杂的,如果这时要进行分割,就必须得有明确的规则支持了
youzelin 2012-12-19
  • 打赏
  • 举报
回复
引用 27 楼 chaojibenben 的回复:
引用 21 楼 youzelin 的回复:引用 楼主 chaojibenben 的回复:字符串如下,如何分割成为三条SQL呢? create table table11(c1 string, c2 string);insert into table11(c1, c2) values('1;abdc;e''fg', 'b');insert into table11(c2,……
为什么不做成存储过程,然后参数通过程序传入存储过程,在存储过程内 begin 一个 transaction 呢?这样既安全又方便。
SLXONLY 2012-12-19
  • 打赏
  • 举报
回复
我觉得只能一点一点的解析了。因为SQL命令开头的关键字是可以知道的,比如DELETE,SELECT,INSERT等 先用char[] ch={';'}; string[] s=你的字符串.Split(ch,StringSplitOptions.RemoveEmptyEntries); 然后循环数组,如果数组中是SQL命令开头的关键字,则标记为开始,把后面的数组内容都拼接起来,直到遇到另一个SQL命令开头的关键字,那么先前拼接的就是一个完整SQL语句。
  • 打赏
  • 举报
回复
那您只能用多个单行文本框了
Kevin 2012-12-19
  • 打赏
  • 举报
回复
引用 26 楼 lyq8376 的回复:
SQL语句不应该由用户自己录入吧?
数据库驱动程序
Kevin 2012-12-19
  • 打赏
  • 举报
回复
引用 21 楼 youzelin 的回复:
引用 楼主 chaojibenben 的回复:字符串如下,如何分割成为三条SQL呢? create table table11(c1 string, c2 string);insert into table11(c1, c2) values('1;abdc;e''fg', 'b');insert into table11(c2, c1) values('2', 'z')……
数据库比较弱智,不支持多条语句。
  • 打赏
  • 举报
回复
SQL语句不应该由用户自己录入吧?
Kevin 2012-12-19
  • 打赏
  • 举报
回复
引用 23 楼 lvoers 的回复:
瞎扯,一点规律都没有的东西也拿出来讨论。你还不如从问题根源着手。为什么要这样拆分它。
数据库不支持执行多条命令,只能一条一条的执行,不拆分请问如何玩儿?
轩威护理 2012-12-19
  • 打赏
  • 举报
回复
string[] sql="你的字符串".Split(';'); sql[0]、sql[1]和sql[2]就是你的SQL语句
lvoers 2012-12-19
  • 打赏
  • 举报
回复
瞎扯,一点规律都没有的东西也拿出来讨论。你还不如从问题根源着手。为什么要这样拆分它。
youzelin 2012-12-19
  • 打赏
  • 举报
回复
引用 20 楼 hjywyj 的回复:
string str = "create table table11(c1 string, c2 string);insert into table11(c1, c2) values('1;abdc;e''fg', 'b');insert into table11(c2, c1) values('2', 'z');"; var ary = Re……
如果单引号里面还有闭括号呢……,如果单引号里面还有 insert、update 呢?
youzelin 2012-12-19
  • 打赏
  • 举报
回复
引用 楼主 chaojibenben 的回复:
字符串如下,如何分割成为三条SQL呢? create table table11(c1 string, c2 string);insert into table11(c1, c2) values('1;abdc;e''fg', 'b');insert into table11(c2, c1) values('2', 'z');
请问客户的需求是什么?根据你所说的,我感觉这是你对于客户需求的理解之后的做出的中间的输出数据。能具体说一下客户的原本需求吗?或许根据需求,完全可以避免并采用另外的方式实现。
  • 打赏
  • 举报
回复
string str = "create table table11(c1 string, c2 string);insert into table11(c1, c2) values('1;abdc;e''fg', 'b');insert into table11(c2, c1) values('2', 'z');"; var ary = Regex.Matches(str, @"(insert|create|select|update|delete)(\([^)]+\)|\s|\w)+;").OfType<Match>().Select(t => t.Value).ToArray();
cs张 2012-12-19
  • 打赏
  • 举报
回复
引用 18 楼 chaojibenben 的回复:
引用 17 楼 crf_net 的回复: 楼主,我建议你这样。在批量插入记录的时候。以下方面比较效率 insert into tablename values('a','b','c'),('a1','b1','c1'),('a2','b2','c2'); sql="insert into tablename values"; 'a','b','c',分别存入数组,然后用","把他们连接起来……
只想说~去他大爷的客户!
Kevin 2012-12-19
  • 打赏
  • 举报
回复
引用 17 楼 crf_net 的回复:
楼主,我建议你这样。在批量插入记录的时候。以下方面比较效率 insert into tablename values('a','b','c'),('a1','b1','c1'),('a2','b2','c2'); sql="insert into tablename values"; 'a','b','c',分别存入数组,然后用","把他们连接起来“('a','b'……
唉,你这建议对咱们码农没有问题,客户涅?客户都是大爷,他可不惯咱们这小脾气~
晟蒷 2012-12-19
  • 打赏
  • 举报
回复
楼主,我建议你这样。在批量插入记录的时候。以下方面比较效率 insert into tablename values('a','b','c'),('a1','b1','c1'),('a2','b2','c2'); sql="insert into tablename values"; 'a','b','c',分别存入数组,然后用","把他们连接起来“('a','b','c')” 然后将其存入数组,连接起来('a','b','c'),('a1','b1','c1'),('a2','b2','c2')。懂了么?
加载更多回复(16)

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧