如何从SQL语句中得到相关的表名

hbjmdx008 2006-06-22 09:05:50
SQL语句,可能比较简单,也可能比较复杂.
昨天做了一天,也没做成,请高手帮一下.
...全文
391 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjz_yang 2006-06-29
  • 打赏
  • 举报
回复
Public Function GetTableName(Sql, conn) As String
'作用:获得所有在SQL语句中出现的表,把他传回去。
'在from 后的,和from 后边的","后的,的一个单词,join后边的单词,
'得到从from 到 where 或)或ORDER,GROUP,HAVING,UNION,COMPUTE,OPTION 之间的所有字符,然后如果得到from 后的
'第一个单词,得到每一个“,”后的第一个单词,得到join 后的单词.
Dim i, J, K, arr
Dim TempSql1, TempSql2, TempSql3, EndTemp
Sql = UCase(Sql)
arr = ""
'''''Debug.Print Sql
For i = 1 To Len(Sql)
J = J + 1
TempSql1 = 0
TempSql1 = InStr(i, Sql, "FROM")
If TempSql1 <> 0 Then
i = TempSql1
TempSql3 = Mid(Sql, i, Len(Sql) - i + 1)
arr = arr + "@" + TempSql3
End If
Next
arr = Mid(arr, 2, Len(arr) - 1)

arr = Split(arr, "@")

'在每个from 后边都有表的存在,要提出来。

On Error Resume Next
Dim allTable, arrkey(10), temp4, L, temp5, temp6, tFlag
tFlag = 0
For i = 0 To UBound(arr)
arrkey(0) = "WHERE": arrkey(1) = "GROUP": arrkey(2) = "HAVING": arrkey(3) = "ORDER": arrkey(4) = "FROM"

'from aa a ,bb,cc,dd d join dfd df

For K = 0 To 4
TempSql2 = arrkey(K)
EndTemp = InStr(5, arr(i), TempSql2)

If EndTemp <> 0 Then

tFlag = 1
allTable = allTable & "@" & SubTable(arr(i), 5, EndTemp)
'''''Debug.Print "frstjobs:", allTable
'提出每个‘,’后和JOION后的第一个单词。
'先找‘,’
temp5 = 1
For L = 0 To Len(arr(i))
'找到每一个‘,’后边的单词
temp5 = InStr(L, arr(i), ",")

If temp5 <> 0 Then
'找到了,把它后边最后一个单词传回来

allTable = allTable + "@" + SubTable(arr(i), temp5, Len(arr(i)))
DoEvents
'''''Debug.Print L
'在从这个位置开始找

L = temp5
End If


Next


'再找JOIN 找到第一个join 成功
For L = 0 To Len(arr(i))
'找到每一个‘JOIN’后边的单词
temp6 = InStr(L, arr(i), "JOIN")
If temp6 <> 0 Then

'找到了,把它后边最后一个单词传回来
allTable = allTable + "@" + SubTable(arr(i), temp6 + 5, Len(arr(i)))
DoEvents
'在从这个位置开始找
L = temp6
End If

Next


End If

Next
If tFlag = 0 Then
'什么也没有
allTable = allTable & "@" & SubTable(arr(i), 5, Len(arr(i)))

' '''''Debug.Print arr(i)

For L = 0 To Len(arr(i))
'找到每一个‘,’后边的单词
temp5 = InStr(L, arr(i), ",")

If temp5 <> 0 Then
'找到了,把它后边最后一个单词传回来

allTable = allTable + "@" + SubTable(arr(i), temp5, Len(arr(i)))
DoEvents
'在从这个位置开始找

L = temp5
End If


Next


'再找JOIN 找到第一个join 成功
For L = 0 To Len(arr(i))
'找到每一个‘JOIN’后边的单词
temp6 = InStr(L, arr(i), "JOIN")
If temp6 <> 0 Then

'找到了,把它后边最后一个单词传回来
allTable = allTable + "@" + SubTable(arr(i), temp6 + 5, Len(arr(i)))
DoEvents
'在从这个位置开始找
L = temp6
End If

Next

End If

Next

'所表可能的表为allTable
'要测试一下,如果在查询不出错,并且表中没有现在的表,就说明是正确的表。
Dim ArrTable, arrAllTable
ArrTable = Split(allTable, "@")
For i = 0 To UBound(ArrTable)
Err.Clear
conn.Execute "select top 1 * from " & ArrTable(i)
If Err.Number = 0 And InStr(arrAllTable, ArrTable(i)) = 0 Then
arrAllTable = arrAllTable + "," + ArrTable(i)
End If

Next
'这样arrAllTable就是所要的表了。除去最前边的@就可以返回了。
GetTableName = Mid(arrAllTable, 2, Len(arrAllTable) - 1)
End Function

Public Function SubTable(Sql, statNum, endNum) As String
'找到给定的区域内的第一个单词
Dim K '查询出内包括的表。
Dim temp1, t, t1, temp2, m
For K = statNum To endNum
'找到第一个表名
If Mid(Sql, K, 1) = " " Or Mid(Sql, K, 1) = "," Or Mid(Sql, K, 1) = "." Then
t = 0
'temp1 = temp1 & Mid(Sql, K, 1)
If t = 0 And t1 = 1 Then

temp1 = temp1 & Mid(Sql, K, 1)
'Debug.Print "sssdd", Trim(Mid(temp1, 1, Len(temp1) - 1))
'删除可能存在的( )
'Debug.Print "left:", Left(temp1, 1)
For m = 0 To 3
If Left(temp1, 1) = "(" Or Left(temp1, 1) = "{" Or Left(temp1, 1) = "[" Then

temp1 = Mid(temp1, 2, Len(temp1))

DoEvents

End If

If Right(temp1, 1) = "(" Or Right(temp1, 1) = "{" Or Right(temp1, 1) = "[" Then

temp1 = Mid(temp1, 2, Len(temp1))

DoEvents

End If
Next



'''Debug.Print "dd", Trim(Mid(temp1, 1, Len(temp1) - 1))
SubTable = Trim(Mid(temp1, 1, Len(temp1) - 1))
'Debug.Print "st:", SubTable
Exit For

End If


Else
'向下走
temp1 = temp1 & Mid(Sql, K, 1)
t1 = 1
End If
Next
End Function

whxleem 2006-06-22
  • 打赏
  • 举报
回复
那道from后面的字符串后可以到数据库中去验证一下 是表 还是试图等
kuailewangzi1212 2006-06-22
  • 打赏
  • 举报
回复
SELECT

(case when a.colorder=1 then d.name else '' end)表名,

a.colorder 字段序号,

a.name 字段名,

(case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else '' end) 标识,

(case when (SELECT count(*)

FROM sysobjects

WHERE (name in

(SELECT name

FROM sysindexes

WHERE (id = a.id) AND (indid in

(SELECT indid

FROM sysindexkeys

WHERE (id = a.id) AND (colid in

(SELECT colid

FROM syscolumns

WHERE (id = a.id) AND (name = a.name))))))) AND

(xtype = 'PK'))>0 then '√' else '' end) 主键,

b.name 类型,

a.length 占用字节数,

COLUMNPROPERTY(a.id,a.name,'PRECISION') as 长度,

isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as 小数位数,

(case when a.isnullable=1 then '√'else '' end) 允许空,

isnull(e.text,'') 默认值,

isnull(g.[value],'') AS 字段说明



FROM syscolumns a left join systypes b

on a.xtype=b.xusertype

inner join sysobjects d

on a.id=d.id and d.xtype='U' and d.name<>'dtproperties'

left join syscomments e

on a.cdefault=e.id

left join sysproperties g

on a.id=g.id AND a.colid = g.smallid

order by a.id,a.colorder
liangpei2008 2006-06-22
  • 打赏
  • 举报
回复
为什么要实现这些?详细说一下,是不是从另外的角度来实现你的需求!
hbjmdx008 2006-06-22
  • 打赏
  • 举报
回复
我的问题是:
如何从一条任意的语句中提出所表的表.
hbjmdx008 2006-06-22
  • 打赏
  • 举报
回复
多谢两位回答,可是:
from 后边不一定就是表呀.
有可能是:
1.后边是多个表并用","连接
2.后边是用SELECT 语句生成.
3.后边是用join 连接.
hbjmdx008 2006-06-22
  • 打赏
  • 举报
回复
是不是不能这样,我的思路是:
用VB
'在from 后的,和from 后边的","后的,的一个单词,join后边的单词,
'得到从from 到 where 或)或ORDER,GROUP,HAVING,UNION,COMPUTE,OPTION 之间的所有字符,然后如果得到from 后的
'第一个单词,得到每一个“,”后的第一个单词,得到join 后的单词.
'把这些单词记录下来就是所表的表.
chouer523 2006-06-22
  • 打赏
  • 举报
回复
什麼意思啊
zlp321002 2006-06-22
  • 打赏
  • 举报
回复
sql 语句? 解析下 from 后面的字符啊!就是表名!!??
Ripple_wang 2006-06-22
  • 打赏
  • 举报
回复
樓主沒把聞題說明白啊
hbjmdx008 2006-06-22
  • 打赏
  • 举报
回复
再UP.在线等呀.
hbjmdx008 2006-06-22
  • 打赏
  • 举报
回复
自已UP

34,875

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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