access生成sql脚本,通过VBA调用ADOX。

使用 MS Access 2016 的VBA,读取mdb文件中的所有表结构(数据类型/长度/精度等),生成对应的SQL create table语句,将结果SQL脚本保存到文件,每个表一行。

access数据库中提取表结构,生成sql查询语句,通过sql脚本可以建表

原文来自http://access911.net/fixhtm/72fab11e16dcebf3.htm?tt=

对原文代码做出的修改:

  1. 原来的代码在生成文件后又使用了生成的sql语句进行创建,下面的代码删除了创建部分。
  2. 原来的代码decimal数据类型没有保留小数位数,下面的代码进行了添加。

运行原代码的问题:

缺少引用的库出错,在下图中的引用上要加入相应的依赖库。





这个最坑,直接百度、google不到,试出来的……

生成的sql语句在access中不能直接运行

由于access语句不支持decimal、nvarchar等数据类型,如果需要运行生成的sql语句需要在其它的软件中处理,或者使用查找替换更改数据类型。

  1. Option Compare Database
  2. Function CreateSQLString(ByVal FilePath As String) As Boolean
  3. '本函数根据当前MDB中的表创建一个 *.jetsql 脚本
  4. '这个函数不是最完美的解决方案,因为 JET SQL DDL 语句不支持一些 ACCESS 特有的属性(DAO支持)
  5. 'This function create a "*.jetsql" script based on current mdb tables.
  6. 'This function is not the BEST, because the JET SQL DDL never support some DAO property.
  7. Dim MyTableName As String
  8. Dim MyFieldName As String
  9. Dim MyDB As New ADOX.Catalog
  10. Dim MyTable As ADOX.Table
  11. Dim MyField As ADOX.Column
  12. Dim pro
  13. Dim iC As Long
  14. Dim strField() As String
  15. Dim strKey As String
  16. Dim strSQL As String
  17. Dim strSQLScript As String
  18. Dim objFile, stmFile
  19. Dim strText As String
  20. On Error GoTo CreateSQLScript_Err
  21. MyDB.ActiveConnection = CurrentProject.Connection
  22. For Each MyTable In MyDB.Tables
  23. If MyTable.Type = "TABLE" Then
  24. '指定表的类型,例如“TABLE”、“SYSTEM TABLE”或“GLOBAL TEMPORARY”或者“ACCESS TABLE”。
  25. 'ADOX 无法判断该表是否已经被删除,还有两种方式判断,
  26. '方法一:(用 DAO)
  27. 'If CurrentDb.TableDefs(strTableName).Attributes = 0 Then
  28. '方法二:(在判断 ADOX.Table.Type 的基础上再判定表名)
  29. 'If Left(MyTable.Name, 7) <> "~TMPCLP" Then
  30. strSQL = "create table [" & MyTable.Name & "]("
  31. For Each MyField In MyTable.Columns
  32. ReDim Preserve strField(iC)
  33. strField(iC) = SQLField(MyField)
  34. iC = iC + 1
  35. Next
  36. strSQL = strSQL & Join(strField, ",")
  37. '获取当前表的字段信息后立即重新初始化 strField 数组
  38. iC = 0
  39. ReDim strField(iC)
  40. '加入键信息
  41. strKey = SQLKey(MyTable)
  42. If Len(strKey) <> 0 Then
  43. strSQL = strSQL & "," & strKey
  44. End If
  45. strSQL = strSQL & ");" & vbCrLf
  46. strSQLScript = strSQLScript & strSQL
  47. 'Debug.Print SQLIndex(MyTable) 'Never support the INDEX,to be continued...
  48. '暂未支持 index 脚本,未完待续...
  49. End If
  50. Next
  51. Set MyDB = Nothing
  52. 'create the Jet SQL Script File
  53. Set objFile = CreateObject("Scripting.FileSystemObject")
  54. Set stmFile = objFile.CreateTextFile(FilePath, True)
  55. stmFile.Write strSQLScript
  56. stmFile.Close
  57. Set stmFile = Nothing
  58. Set objFile = Nothing
  59. CreateSQLScript = True
  60. CreateSQLScript_Exit:
  61. Exit Function
  62. CreateSQLScript_Err:
  63. MsgBox Err.Description, vbExclamation
  64. CreateSQLScript = False
  65. Resume CreateSQLScript_Exit
  66. End Function
  67. Function RunFromText(ByVal FilePath As String)
  68. '本函数将 CreateSQLScript 生成的 *.jetsql 脚本来生成 mdb 数据库中的表
  69. 'This Function run the "*.jetsql" which is created by CreateSQLScript to create the tables in current mdb database.
  70. On Error Resume Next
  71. Dim objFile, stmFile
  72. Dim strText As String
  73. Set objFile = CreateObject("Scripting.FileSystemObject")
  74. Set stmFile = objFile.OpenTextFile(FilePath, 1, False)
  75. strText = stmFile.ReadAll
  76. stmFile.Close
  77. Set stmFile = Nothing
  78. Set objFile = Nothing
  79. Dim strSQL() As String
  80. Dim i As Long
  81. strSQL = Split(strText, ";" & vbCrLf)
  82. For i = LBound(strSQL) To UBound(strSQL)
  83. CurrentProject.Connection.Execute Trim(strSQL(i))
  84. If Err <> 0 Then
  85. Debug.Print "Error SQL is:" & strSQL(i)
  86. Err.Clear
  87. End If
  88. Next
  89. End Function
  90. Function SQLKey(ByVal objTable As ADOX.Table)
  91. '调用 ADOX 生成有关“键”的 JET SQL DDL 子句
  92. 'Reference ADOX and create the JET SQL DDL clause about the "Key"
  93. Dim MyKey As ADOX.Key
  94. Dim MyKeyColumn As ADOX.Column
  95. Dim strKey As String
  96. Dim strColumns() As String
  97. Dim strKeys() As String
  98. Dim i As Long
  99. Dim iC As Long
  100. For Each MyKey In objTable.Keys
  101. Select Case MyKey.Type
  102. Case adKeyPrimary
  103. strKey = "Primary KEY "
  104. Case adKeyForeign
  105. strKey = "FOREIGN KEY "
  106. Case adKeyUnique
  107. strKey = "UNIQUE "
  108. End Select
  109. For Each MyKeyColumn In MyKey.Columns
  110. ReDim Preserve strColumns(iC)
  111. strColumns(iC) = "[" & MyKeyColumn.Name & "]"
  112. iC = iC + 1
  113. Next
  114. ReDim Preserve strKeys(i)
  115. strKeys(i) = strKey & "(" & Join(strColumns, ",") & ")"
  116. '获取信息后,立即初始化数组
  117. iC = 0
  118. ReDim strColumns(iC)
  119. i = i + 1
  120. Next
  121. SQLKey = Join(strKeys, ",")
  122. End Function
  123. Function SQLField(ByVal objField As ADOX.Column)
  124. '调用 ADOX 生成有关“字段”的 JET SQL DDL 子句
  125. 'Reference ADOX and create the JET SQL DDL clause about the "Field"
  126. Dim p As String
  127. Select Case objField.Type
  128. Case 11
  129. p = " yesno"
  130. Case 6
  131. p = " money"
  132. Case 7
  133. p = " datetime"
  134. Case 5
  135. p = " FLOAT" 'or " Double"
  136. Case 72
  137. 'JET SQL DDL 语句无法创建“自动编号 GUID”字段,这里暂时用
  138. '[d] GUID default GenGUID() 代替部分功能,详情请看文章
  139. '如何用JET SQL DDL创建自动编号GUID字段
  140. 'http://access911.net/?kbid;72FABE1E17DCEEF3
  141. If objField.Properties("Autoincrement") = True Then
  142. p = " autoincrement GUID"
  143. Else
  144. p = " GUID"
  145. End If
  146. Case 3
  147. If objField.Properties("Autoincrement") = False Then
  148. p = " smallint"
  149. Else
  150. p = " AUTOINCREMENT(1," & objField.Properties("Increment") & ")"
  151. End If
  152. Case 205
  153. p = " image"
  154. Case 203
  155. p = " memo" 'Access "HyperLink" field is also a MEMO data type.
  156. 'ACCESS 的超级链接也是 MEMO 类型的
  157. Case 131
  158. p = " DECIMAL"
  159. p = p & "(" & objField.Precision & "," & objField.NumericScale & ")"
  160. Case 4
  161. p = " single" 'or " REAL"
  162. Case 2
  163. p = " smallint"
  164. Case 17
  165. p = " byte"
  166. Case 202
  167. p = " nvarchar"
  168. p = p & "(" & objField.DefinedSize & ")"
  169. Case 130
  170. '指示一个以 Null 终止的 Unicode 字符串 (DBTYPE_WSTR)。 这种数据类型用 ACCESS 设计器是无法设计出来的。
  171. '20100826 新增
  172. p = " char"
  173. p = p & "(" & objField.DefinedSize & ")"
  174. Case Else
  175. p = " (" & objField.Type & " Unknown,You can find it in ADOX's help. Please Check it.)"
  176. End Select
  177. p = "[" & objField.Name & "]" & p
  178. If IsEmpty(objField.Properties("Default")) = False Then
  179. p = p & " default " & objField.Properties("Default")
  180. End If
  181. If objField.Properties("Nullable") = False Then
  182. p = p & " not null"
  183. End If
  184. SQLField = p
  185. End Function
  186. 'Please copy these code in VBA module and press F5 to run the follow function
  187. '请将以下代码 COPY 到 VBA 模块中,然后按 F5 键运行以下两段函数 生成的sql文件目标路径
  188. Sub RunTest_CreateScript()
  189. CreateSQLString "d:\temp.jetsql"
  190. End Sub

access生成sql脚本,通过VBA调用ADOX的更多相关文章

  1. PowerDesigner PDM生成sql脚本时:表的名称和表里面的字段名称都有引号解决。。。

    PowerDesigner PDM生成sql脚本时:表的名称和表里面的字段名称都有引号解决... 1.当你的PowerDesigner 是新安装时,你得设置可能就会出现一些问题,在这里比如:PDM生成 ...

  2. PowerDesigner16.5 生成SQL脚本执行出错:collate chinese_prc_ci_as

    PowerDesigner16.5 生成SQL脚本执行出错, collate chinese_prc_ci_as 点DataBase-edit current dbms —— 左边Script - O ...

  3. PD 15.1 安装 破解 , 简单使用 (一对多,多对多关系生成sql脚本) , CDM 和 PDM 的区别;PD15.1 生成sql2008 无FK外键约束的解决方法

    CDM是概念模型,在概念模型上没有具体数据库产品的概念,反映的是实体和联系.PDM是物理模型,是依赖具体数据库产品的模型,比如可以指定具体的数据类型和约束等等.在PowerDesigner中两个模型之 ...

  4. (转)powerdesigner 生成sql脚本使用的设置

    本文转载自:http://blog.163.com/lizhihaoo@126/blog/static/103121661201036171115/ 1. 生成sql脚本的时候,提示"con ...

  5. PowerDesigner生成sql脚本

    1.打开PowerDesigner->New Project; 2.填写项目名称,选择文件的存放路径: 3.新建一个模型,New Model: 4.选择概念模型,填写模型名称: 5.选择enti ...

  6. SQL Server ----- 生成sql 脚本

    通过生成sql 脚本进行数据库转移 选中需要进行转移的数据库 点击生成脚本后出现 进入的是简介界面    直接点击下一步 进入到选择对象界面. 按照步骤进行设置     选择你需要的    架构和数据 ...

  7. 读取excel数据生成sql脚本

    package com.interact.util; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; import jxl.read.b ...

  8. SNF快速开发平台MVC-EasyQuery-拖拽生成SQL脚本

    在之前介绍一下EasyQuery工具SNF开发平台WinForm-EasyQuery统计分析-效果-非常牛逼的报表查询工具 Winform开发框架之图表报表在线设计器-报表-SNF.EasyQuery ...

  9. 去掉PowerDesigner生成SQL脚本中字段名带的引号

    使用PowerDesigner生成数据库建表SQL脚本时,尤其是Oracle数据库时,表名一般会带引号.其实加引号是PL/SQL的规范,数据库会严格按照“”中的名称建表,如果没有“”,会按照ORACL ...

随机推荐

  1. Xor && 线性基练习

    #include <cstdio> #include <cstring> ; ; int cnt,Ans,b,x,n; inline int Max(int x,int y) ...

  2. Golang游戏服务器

    我对和GOLANG写MMO服务器的一些遐想: 1.沙盒(隔离性) SKYNET:原生LUA STATE作为沙盒, 进行服务器间隔离安全性高: 服务可以很容易的配置到不同节点之上. GO:估计用RECO ...

  3. 一键编译go文件命令.bat

    一键编译go文件命令.bat    , 请新建 一键编译go文件命令.bat    文件,放到你的xxx.go文件目录下 ( 欢迎加入go语言群: 218160862 , 群内有实践) 点击加入 @e ...

  4. Hibernate 的两种配置

    前言:不管是注解配置还是xml,都是告诉hibernate你想创建什么样的数据表,几张数据表中的关系是什么,仅此而已,剩下的不过就是hibernate的优化了. 所以从创建数据表的ddl语句和数据表的 ...

  5. 研华运动控制卡 SoftMotion 技术简介

    SoftMotion为研华在设备自动化中的一项重要核心技术,相较于过去市面上ASIC 运动控制解决方案,研华自动化团队自主技术开发软件运动控制技术,并且透过现场可程序逻辑门阵列 (FPGA, Fiel ...

  6. python webdriver 自动化测试练习 1-- 在线调查

    __author__ = 'Mickey0s' # coding:utf8 from selenium import webdriver from selenium.webdriver.common. ...

  7. selenium获取多窗口句柄并一一切换至原窗口句柄(三个窗口)

    网上有很多是selenium基于python来获取两个窗口句柄与切换,本文实现用python+selenium获取多窗口句柄并一一切换至原窗口句柄(三个窗口),且在每个窗口下进行一个搜索或翻译,然后截 ...

  8. IO消息机制

    同步阻塞 同步非阻塞 异步阻塞 异步非阻塞 同步是函数自身等待结果 异步可采用状态轮询/通知/回调 返回结果: 阻塞和非阻塞的关注点是在等待消息的时候 线程的状态 同步阻塞 线程挂起 逻辑上函数不马上 ...

  9. JS对象实现随机满天小星星实例

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. node.js Websocket实现扫码二维码登录---GoEasy

    最近在做一个扫码登录功能,为此我还在网上搜了一下关于微信的扫描登录的实现方式.当这个功能完成了后,我决定将整个实现思路整理出来,方便自己以后查看也方便其他有类似需求的程序猿些. 要实现扫码登录我们需要 ...