Microsoft Access在具有已知值的表中查找字段

时间:2012-08-07 17:31:11

标签: sql vba ms-access odbc

我们有一个相当大的Oracle数据库,我们可以通过Microsoft Access和ODBC以只读访问方式连接。我们使用的是与幕后结构不匹配的前端系统,我经常需要通过Microsoft Access查询系统。问题是我们没有提供任何关于结构和结构的文件需要认真关注。搜索我需要的字段非常耗时。

使用我们的前端,我能够查看我想要查询的值,并且我知道关键字段,但我需要找到包含已知值的字段。

如果我有一条记录,我知道字段“A”的值,并且字段“X”的值,是否可以查询字段“X”?

前端显示

Student ID: 12345678
Payments: 23456

后端

TechID: 12345678
???: 23456

我可以查询“???”

2 个答案:

答案 0 :(得分:2)

您可以通过迭代表的集合以及每个表的字段集合来完成此操作。

Open Database
Get all Tables
For Each Table
   Get all Fields
   For Each Field
       If Field type is text ... and
       If Field size is not TOO Long ...
           Search for string
           If found, write to a results bucket
   Next
Next

以下是编目表(源here

的代码示例
Public Function GenerateDataDictionary(aDataDictionaryTable As String)
'***       Usage: GenerateDataDictionary("MyDataDictionaryTable")
'*** Extracts the information about the tables for the data dictionary 
'*** and inserts it to a table named aDataDictionaryTable

    Dim tdf As TableDef, fldCur As Field, colTdf As TableDefs
    Dim rstDatadict As Recordset
    Dim i As Integer, j As Integer, k As Integer
    Set rstDatadict = CurrentDb.OpenRecordset(aDataDictionaryTable)
    Set colTdf = CurrentDb.TableDefs

    'Go through the database and get a tablename   
    For Each tdf In CurrentDb.TableDefs
    'Do what you want with the table names here.
    rstDatadict.AddNew
    rstDatadict.Update   
rstDatadict.AddNew
    rstDatadict![Table] = tdf.NAME
    rstDatadict![Field] = "----------------------------"
    rstDatadict![Display] = "----------------------------"
    rstDatadict![Type] = ""
    rstDatadict.Update
    rstDatadict.AddNew
    rstDatadict![Table] = "Table Description:"
    For j = 0 To tdf.Properties.Count - 1
          If tdf.Properties(j).NAME = "Description" Then
              rstDatadict![Field] = tdf.Properties(j).Value
          End If
    Next j

    rstDatadict.Update 
    rstDatadict.AddNew
    rstDatadict.Update

For i = 0 To tdf.Fields.Count - 1
          Set fldCur = tdf.Fields(i)          
          rstDatadict.AddNew
          rstDatadict![Table] = tdf.NAME
          rstDatadict![Field] = fldCur.NAME
          rstDatadict![Size] = fldCur.Size

          Select Case fldCur.Type
            Case 1
              FieldDataType = "Yes/No"
            Case 4
              FieldDataType = "Number"
            Case 8
              FieldDataType = "Date"
            Case 10
              FieldDataType = "String"
            Case 11
              FieldDataType = "OLE Object"
            Case 12
              FieldDataType = "Memo"
            Case Else    ' Other values.
              FieldDataType = fldCur.Type
          End Select

          rstDatadict![Type] = FieldDataType                                
                For j = 0 To tdf.Fields(i).Properties.Count - 1
                    If fldCur.Properties(j).NAME = "Description" Then
                        rstDatadict![DESCRIPTION] = fldCur.Properties(j).Value
                    End If

                    If fldCur.Properties(j).NAME = "Caption" Then
                        rstDatadict![Display] = fldCur.Properties(j).Value
                    End If

                    If fldCur.Properties(j).NAME = "Rowsource" Then
                        rstDatadict![LookupSQL] = fldCur.Properties(j).Value
                    End If
                Next j

            rstDatadict.Update

    Next i
    Debug.Print "  " & tdf.NAME
    Next tdf

End Function

您可以通过创建一个连接到表名表的字段名表来对Access中的结果进行编目。然后,您的搜索基于目录而不是原始集合。

我以这种方式反向设计MAS 90的架构(使用JobOps插件)。没有地图,但我有一个只读的ODBC连接,我用的方式就是你提出的方式。采购会计师会给我一个独特的产品编号,我会通过这个综合引擎来运行它。随着时间的推移,我成功地将包括18k字段的700个表格提取到20个表格和几百个字段。这使我们可以导出我们的数据。

答案 1 :(得分:1)

你的问题的答案很简单。不,你做不到。

我能想到两种解决方案。第一种是手动将所有值连接在一起,然后查找包含该值的行。这不完美,但可能有效:

select *
from (select t.*, ('|'""col1||'|'||col2+'|' . . .||'|') as allcols
      from t
     ) t
where instr('|23456|', allcols) > 0

这将找到列中具有该值的任何行。可能足够接近你想要的东西。

第二种是使用UNPIVOT做同样的事情。

我强烈建议您花一点时间来查找字段之间的映射,然后在Oracle中创建一个具有应用程序中显示的字段名称的视图。听起来这会让你在中期内省下很多努力。