Office中国论坛/Access中国论坛

标题: 求教:如何分解sql语句 [打印本页]

作者: 风中漫步    时间: 2015-8-6 13:12
标题: 求教:如何分解sql语句
如有条复杂的sql,想要分解出字段,表名,条件,函数,等等,该如何代码?请指教,谢谢
如:select a,b,c,d from table1 where (a='''1''') and (b='''1''')。当然,这个不够复杂,就是表达一下意思

作者: 轻风    时间: 2015-8-6 13:18
用InStr函数获取from,where等关键字的位置,再用MID截取文本
作者: 风中漫步    时间: 2015-8-6 13:28
轻风 发表于 2015-8-6 13:18
用InStr函数获取from,where等关键字的位置,再用MID截取文本

谢谢。这个方法老麻烦了,目前在用。至今我还只是用到哪写到哪,求个终极方法,有代码更佳
作者: HKEY_CURRENT    时间: 2015-8-6 14:06
正则表达式
作者: 风中漫步    时间: 2015-8-6 14:11
HKEY_CURRENT 发表于 2015-8-6 14:06
正则表达式

想到过,不会用。求例。谢
作者: HKEY_CURRENT    时间: 2015-8-6 14:21
风中漫步 发表于 2015-8-6 14:11
想到过,不会用。求例。谢

嘿嘿,我也不是很会
作者: roych    时间: 2015-8-6 14:23
没搞懂这个拿来干吗。
1、where是条件子句,不过having也是噢。而且加上group by,order by还得考虑顺序
2、倘若嵌套子查询时(特别是多重的时候)肿么办?
如果说,由用户自定义查询条件,论坛里有不少例子,没必要钻这个牛角尖。
作者: 风中漫步    时间: 2015-8-6 15:32
roych 发表于 2015-8-6 14:23
没搞懂这个拿来干吗。
1、where是条件子句,不过having也是噢。而且加上group by,order by还得考虑顺序
...

呵呵,斑竹高大上惯了,可能不需要考虑这些。
我一般用民间数据库,它们比较简陋,一般仅会分发动态库和命令行窗口。如果想再进一步,一般就得自己动手。有的数据库是按字段存储在系统表中,有的仅有一条sql.在建立图形界面时就要提取分拆sql.以前只处理了表部分的部分,代码却写了非常多。有点疲劳。
你昨天发的那个sql界面估计也分拆了sql.我用的部分库要想图形化,暂时还没想到有比不拆更好的方法。
这是我昨天仿写的一个,就需要数据填充[attach]57017[/attach]

作者: 风中漫步    时间: 2015-8-6 15:37
HKEY_CURRENT 发表于 2015-8-6 14:21
嘿嘿,我也不是很会

,也谢谢点拨
作者: zpy2    时间: 2015-8-7 06:17
不懂?什么叫民间库?
作者: 风中漫步    时间: 2015-8-7 14:46
zpy2 发表于 2015-8-7 06:17
不懂?什么叫民间库?

就是正式公司之外的软件
作者: 风中漫步    时间: 2015-8-7 14:47
跪等大神{:soso_e120:}
作者: wang1999    时间: 2015-8-8 16:21
以前写过一个有点类似的很简单的解释器
SortLBFromPoint
不知道还能不能找得到
作者: wang1999    时间: 2015-8-8 16:39
以前写的, 作为单击列表框首行,排序用的, 很乱. 后来没用了.{:soso_e110:}太久了.一路过来,要是直接学C多好(弯路会少走不少)
这里作了两部分分析 字段/表,及排序/分组.  与你的情况有点类似.其实可以单独写一个解释器




作者: wang1999    时间: 2015-8-8 16:43


  1.     Dim astrSQLNew() As String, strAlias As String, strTagOrder As String        '新SQLL语句数组; 别名; 排序标记符号
  2. '字段名称; 字段全名(含表名或为AS前一个字符串); 输入名称(显示名称)
  3. Dim strField As String, strFieldSort As String, strInputName As String
  4. Dim strFROMBefore As String, strFROMAfter As String, blnSorted As Boolean
  5. Dim i As Integer, p As Integer, strFieldFull As String
  6.     Const conASC As String = "▲", conDESC As String = "▼"        '升序标识符; 降序标识符
  7.     '1) 处理排序符号
  8.     strInputName = SortName
  9.     If TagSortField Then
  10.         strTagOrder = conASC
  11.         If Right(SortName, Len(conASC)) = conASC Then        '末尾为升序,则转为降序
  12.             strInputName = Left(SortName, Len(SortName) - Len(conASC))
  13.             strTagOrder = conDESC
  14.         ElseIf Right(SortName, Len(conDESC)) = conDESC Then        '末尾为降序,则转为升序
  15.             strInputName = Left(SortName, Len(SortName) - Len(conDESC))
  16.             strTagOrder = conASC
  17.         End If
  18.     End If
  19.     '2) 处理 SQL语句(分解成两部分——From之前的语句(不包括Select),From之后的语句(含From))
  20.     i = 1
  21.     Do Until i = p        '将中间连续两个空格替换成一个空格
  22.         i = Len(SQLStatement)
  23.         SQLStatement = Replace(SQLStatement, "  ", " ")
  24.         p = Len(SQLStatement)
  25.     Loop
  26.     SQLStatement = Trim(SQLStatement)        '去除两头的空格
  27.     If Right(SQLStatement, 1) = ";" Then SQLStatement = Left(SQLStatement, Len(SQLStatement) - 1)        '去掉分号
  28.     p = InStr(1, SQLStatement, " FROM ")
  29.     If p = 0 Or Left(SQLStatement, 7) <> "SELECT " Then Err.Raise 5: Exit Function
  30.     strFROMBefore = Left(SQLStatement, p - 1)
  31.     strFROMBefore = Mid(strFROMBefore, 7)        '排除:SELECT
  32.     strFROMAfter = Mid(SQLStatement, p + 1)
  33.     '3) 对strFROMBefore字段部分语句进行处理(加入新排序标记)
  34.     astrSQLNew = Split(strFROMBefore, ",")
  35.     For i = 0 To UBound(astrSQLNew)
  36.         astrSQLNew(i) = Trim(astrSQLNew(i))
  37.         strFieldFull = astrSQLNew(i)
  38.         p = InStr(1, strFieldFull, " As ")
  39.         If p Then        '3.1) 大于0,处理字段名与别名组合的语句
  40.             strAlias = Mid(strFieldFull, p + 4)        '获得别名
  41.             strFieldFull = Left(strFieldFull, p - 1): strField = strFieldFull        '获得字段名
  42.             '如已经处理排序,则只对别名字段作排序符号处理
  43.             If blnSorted Then
  44.                 strAlias = AliasProcess(strAlias, TagSortField)
  45.                 GoTo SorFieldProcess:
  46.             Else
  47.                 '判断字段名是否为排序名称
  48.                 p = InStr(1, strFieldFull, ".")        '从strFieldFull中提取strField
  49.                 If p Then strField = Mid(strFieldFull, p + 1)
  50.                 If strField = strInputName Then        '如为排序字段,则更新语句(加入排序标记)
  51.                     astrSQLNew(i) = strFieldFull & " AS " & strField & strTagOrder
  52.                     blnSorted = True: strFieldSort = strFieldFull
  53.                 Else
  54.                     '判断别名是否为排序名称
  55.                     strAlias = AliasProcess(strAlias, TagSortField)
  56.                     If strAlias = strInputName Then        '如为排序字段,则更新语句(加入排序标记)
  57.                         strAlias = strAlias & strTagOrder
  58.                         p = InStr(1, strAlias, " "): If p Then strAlias = "[" & strAlias & "]"        '如有空格,则加中括号
  59.                         astrSQLNew(i) = strFieldFull & " AS " & strAlias
  60.                         blnSorted = True: strFieldSort = strFieldFull
  61.                     Else        '其他别名(不是排序名称),语句复位(去掉排序标记)
  62. SorFieldProcess:
  63.                         If strAlias = strField Then
  64.                             astrSQLNew(i) = strFieldFull
  65.                         Else
  66.                             p = InStr(1, strAlias, " "): If p Then strAlias = "[" & strAlias & "]"        '如有空格,则加中括号
  67.                             astrSQLNew(i) = strFieldFull & " AS " & strAlias
  68.                         End If
  69.                     End If
  70.                 End If
  71.             End If
  72.         ElseIf Not blnSorted Then        '3.2) 字段处理
  73.             p = InStr(1, strFieldFull, ".")        '从strFieldFull中提取strField
  74.             If p Then strField = Mid(strFieldFull, p + 1)
  75.             If strField = strInputName Then
  76.                 astrSQLNew(i) = strFieldFull & " AS " & strField & strTagOrder
  77.                 blnSorted = True: strFieldSort = strFieldFull
  78.             ElseIf strFieldFull = strInputName Then
  79.                 astrSQLNew(i) = strFieldFull & " AS " & strFieldFull & strTagOrder
  80.                 blnSorted = True: strFieldSort = strFieldFull
  81.             ElseIf (Right(strFieldFull, 1) = "*") Or (Left(strFieldFull, 4) = "All") Or (strFieldFull = "*") Then        '特别处理理保留字"*",没有排序符号的排序
  82.                 strFieldSort = strInputName        '暂定为排序字段
  83.             End If
  84.             '其他字段不做处理
  85.         End If
  86.     Next
  87.     '4) 组合成新的语句
  88.     strFROMBefore = "SELECT " & Join(astrSQLNew, ",")
  89.     p = InStr(1, strFROMAfter, " Order By ")        '对strFROMAfter中排序作更新
  90.     If p Then strFROMAfter = Left(strFROMAfter, p - 1)
  91.     strFROMAfter = strFROMAfter & " Order By " & strFieldSort
  92.     If strTagOrder = conDESC Then strFROMAfter = strFROMAfter & " DESC"        '如果为降序,则加入降序标识符
  93.     ModifySQLSortField = strFROMBefore & " " & strFROMAfter
  94. End Function
  95. 'Purpose:   对别名的排序符号处理
  96. Private Function AliasProcess(ByVal Alias As String, ByVal TagSortField As Boolean) As String
  97.     Const conASC As String = "▲", conDESC As String = "▼"        '升序标识符; 降序标识符
  98.     If Left(Alias, 1) = "[" Then Alias = Mid(Alias, 2, Len(Alias) - 2)        '排除两边的"[]"
  99.     If TagSortField And Right(Alias, Len(conASC)) = conASC Then        '如别名含排序标记,则将删除
  100.         Alias = Left(Alias, Len(Alias) - Len(conASC))
  101.     ElseIf TagSortField And Right(Alias, Len(conDESC)) = conDESC Then
  102.         Alias = Left(Alias, Len(Alias) - Len(conDESC))
  103.     End If
  104.     AliasProcess = Alias
  105. End Function
复制代码

作者: wang1999    时间: 2015-8-8 16:45

  1. '--------------------------------------------------
  2. 'Function:  ModifySQLSortField  V2.1
  3. 'Purpose:   从SQL语句中获得字段名称及别名
  4. 'Input:     输入参数
  5. '       [in]    SQLStatement:[String]选择SQL语句("SELECT"语句)
  6. '       [in]    SortName:[String]需要排序字段名称或者别名
  7. '       [in]    TagSortField:[Boolean]在名称中是否包含排序标记,True:包含,Fasle:不包含
  8. 'Output:    成功返回修改排序字段后SQL字句
  9. 'Refer:     调用过程:AliasProcess
  10. 'PseudoCode:示例代码(伪代码)
  11. '           1. ListBox.RowSource = ModifySQLSortField(ListBox.RowSource, strFieldName, True)   'LB单击事件中,排序列表框,名称中有标记
  12. '           2. ListBox.RowSource = ModifySQLSortField(mRowSource, strFieldName,False)     'LB单击事件中,排序列表框,名称中没有标记
  13. 'Infor:     SQLStatement只能为选择SQL语句("SELECT"语句)(也不能为 SELECT...INTO 语句); TagSortField 一般都为 True
  14. '不能处理含有关键字
  15. '           编写:坚果 2006/01/20 说明:创建  修改:2006/02/25-2006/04/14 说明:经过四次修改,但代码还是冗长(160行之多)
  16. '           修改:2006/05/15 说明:全部重新编写代码,原V1.0中对整个语句进行处理.现对代码语句拆分成两部分处理.代码精简. 修改:2006/05/15 说明:Bug修复
  17. '--------------------------------------------------
  18. Public Function ModifySQLSortField(ByVal SQLStatement As String, ByVal SortName As String, Optional ByVal TagSortField As Boolean = True) As String
  19.     Dim astrSQLNew() As String, strAlias As String, strTagOrder As String        '新SQLL语句数组; 别名; 排序标记符号
  20. '字段名称; 字段全名(含表名或为AS前一个字符串); 输入名称(显示名称)
复制代码


作者: wang1999    时间: 2015-8-8 16:47
贴这代码搞了半天{:soso_e134:},说我有攻击代码, 分成两半才成.
作者: 风中漫步    时间: 2015-8-9 11:21
wang1999 发表于 2015-8-8 16:45

多谢.抽空细看




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3