设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

12
返回列表 发新帖
楼主: 风中漫步
打印 上一主题 下一主题

[其它] 求教:如何分解sql语句

[复制链接]
11#
 楼主| 发表于 2015-8-7 14:46:59 | 只看该作者
zpy2 发表于 2015-8-7 06:17
不懂?什么叫民间库?

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



15#
发表于 2015-8-8 16:43:50 | 只看该作者


  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
复制代码

评分

参与人数 1经验 +5 收起 理由
风中漫步 + 5

查看全部评分

16#
发表于 2015-8-8 16:45:44 | 只看该作者

  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前一个字符串); 输入名称(显示名称)
复制代码

17#
发表于 2015-8-8 16:47:42 | 只看该作者
贴这代码搞了半天{:soso_e134:},说我有攻击代码, 分成两半才成.
18#
 楼主| 发表于 2015-8-9 11:21:02 | 只看该作者

多谢.抽空细看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-8 19:45 , Processed in 0.114489 second(s), 34 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表