【问题标题】:Access: How to find a field in a whole database?访问:如何在整个数据库中查找字段?
【发布时间】:2008-12-22 14:03:07
【问题描述】:

我有一个包含许多表的访问数据库。我正在寻找一个可能存在也可能不存在于一个或多个表中的字段。如何检查它是否存在? (当然不用查询每张表)

【问题讨论】:

    标签: database ms-access


    【解决方案1】:

    字段有一个模式:

    Set cn = CurrentProject.Connection
    
    SelectFieldName = "SomeFieldName" 
    
    'Get names of all tables that have a column = SelectFieldName '
    Set rs = cn.OpenSchema(adSchemaColumns, _
    Array(Empty, Empty, Empty, SelectFieldName))
    

    发件人:MS Access: How to bypass/suppress an error?

    【讨论】:

      【解决方案2】:

      如果您真的不想打开任何表,一个解决方案是使用数据库对象的tabledefs 集合。每个tabledef 项目都有自己的fields 集合供您浏览。它会给出这样的结果:

      Public function findFieldInDatabase(p_myFieldName)
          dim db as database, _
              tb as tabledef, _
              fd as field
      
          set db = currentDb
          for each tb in db.tabledefs
              for each fd in tb.fields
                  if fd.name = p_myFieldName then
                      debug.print tb.name, fd.name
                  end if
              next fd
          next tb
          set fd = nothing
          set tb = nothing
          set db = nothing
      end function 
      

      这个代码可以很容易地接受一个可选的p_myTableName作为参数来限制搜索到一个表/表范围。

      【讨论】:

      • Philippe,你为什么用你的点心做那个“,_”把戏?与多个 dim 相比有什么巨大的优势吗?
      • BIBD,这只是一种垂直堆叠声明的干净方式,无需重复“Dim”关键字。
      【解决方案3】:

      如果我想查看特定表中的特定列(在 strSearch 中标识)是否存在,我会这样做。

      Public Sub search()
      
      Dim db As Database
      Dim strSearch As String
      Dim strSQL As String
      Dim rsResults As Recordset
      Dim i As Integer
      Dim cols As Integer
      
          strSearch = "a3"
      
          Set db = CurrentDb
          strSQL = "select * from bar"
          Set rsResults = db.OpenRecordset(strSQL, dbOpenDynaset, dbReadOnly)
          If Not rsResults.BOF Then
              rsResults.MoveFirst
          End If
      
          cols = rsResults.Fields.Count - 1 ' -1 because we start counting cols at 0
          For i = 0 To cols
              If rsResults(i).Name = strSearch Then
                  MsgBox "Found the seach string"
              End If
          Next
          MsgBox "end of script"
      
      End Sub
      

      现在我知道你不想为每张桌子写一个。所以接下来要做的就是遍历所有的表。您可以使用以下 SQL 找到所有表的列表

      SELECT 
          name
      FROM 
          MSysObjects 
      WHERE 
          (Left([Name],1)<>"~") 
          AND (Left([Name],4) <> "MSys") 
          AND ([Type] In (1, 4, 6)) 
      

      将这两部分连接在一起,我将留给学生作为练习:)

      【讨论】:

      • 有一种更简单的方法使用 ADO Schemas
      • 但是如果代码在 Access 中运行需要额外的库引用(除非你使用后期绑定,我猜)。原始提问者没有明确说明代码将在其中运行的上下文。对我来说,如果您使用 Access 本身,DAO 显然是 Jet 数据的首选。
      • 我的 ', _' 技巧只是变量声明的格式规则。使事情更具可读性。在枚举函数的参数时,您也可以使用相同的技巧。另一个“学校”是 www.stackoverflow.com/questions/166657/do-you-have-your-own-dnutndt-do-not-use-thisnever-do-that-list#166717
      • 是的,我经常使用将参数扩展超过 80 个字符的函数来执行此操作。我仍然倾向于在每条线上单独做一个暗淡。我只是希望它有一些明显的优势(比如执行速度),但每个人都有自己的优势。
      • “对我来说,DAO 显然是 Jet 数据的首选”。但在这种特殊情况下,ADO 解决方案肯定更可取,因为 OpenSchema 返回一个仅包含匹配项的记录集。 DAO 涉及大量循环以自己查找匹配项。额外的参考并不贵!
      【解决方案4】:

      以下是在 MS Access 中使用 VBScript 访问表架构的方法:

      TestData = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=c:\somefolder\YOURDB.mdb"
      Set Conn = Server.CreateObject("ADODB.Connection")
      Conn.Open TestData
      
      Set rs = Conn.OpenSchema(4)
      
      do until Rs.eof
          tn = RS("TABLE_NAME")
          fn = RS("COLUMN_NAME")
          ' your script goes here
      loop
      

      【讨论】:

        【解决方案5】:

        给你:

        Public Function fTableExists(ByVal vstrTable As String) As Boolean
            Dim rs As ADODB.Recordset
            Set rs = CurrentProject.Connection.OpenSchema( _
                   adschematables, Array(Empty, Empty, vstrTable))
            fTableExists = Not rs.EOF
            rs.Close
            Set rs = Nothing
        End Function
        
        Public Function fColumnExists(ByVal vstrTable As String, _
                                      ByVal vstrColumn As String) As Boolean
            Dim rs As ADODB.Recordset
            Set rs = CurrentProject.Connection.OpenSchema(adSchemaColumns, _
              Array(Empty, Empty, vstrTable, vstrColumn))
            fColumnExists = Not rs.EOF
            rs.Close
            Set rs = Nothing
        End Function
        

        【讨论】:

        • 也许对如何使用这些功能的简短说明会有所帮助。特别是这些函数似乎假设一个开放的数据库连接。
        【解决方案6】:

        MSSQL 寻找 ADDRESS1 列: 从 sysobjects 中选择 so.name 所以 where so.id in (select sc.id from syscolumns sc where name like 'ADDRESS1')

        甲骨文 http://en.wikipedia.org/wiki/Oracle_metadata

        Google 会找到其他数据库的语法...

        【讨论】:

        • 数据库是 ms-access。原帖中是这么说的。
        【解决方案7】:

        它是什么类型的数据库?如果是 SQL Server,你可以试试这个:

        SELECT * FROM sysobjects WHERE xtype = 'U' AND name = 'myTable'
        

        但由于它是您要查找的列而不是表(感谢 Brian),请尝试以下操作:

        SELECT 
            DISTINCT
            so.[name] AS 'Table',
            sc.[name] AS 'Column' 
            FROM 
                syscolumns sc
            JOIN
                sysobjects so
                ON
                    so.id = sc.id
            WHERE 
                sc.[name] = 'myTable'
        

        【讨论】:

        • 他在寻找列而不是表格。不过关闭。
        • 数据库是 ms-access。原帖中是这么说的。
        • 不,在修改后的帖子中是这样说的。原帖没有这么说。
        猜你喜欢
        • 2012-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        相关资源
        最近更新 更多